C++:C字符串到std:string

use*_*918 -1 c++ string type-conversion

我正在尝试使用函数将C字符串转换为std :: string.该功能在64位上正常工作gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9).但是当我编译它-O2-O3优化它时,会出现段错误.它适用于-O1.有人可以建议修复或解决这个问题吗?功能如下:

void make_name(unsigned const &i, string &h_file)
{
        char h_str[10];
        sprintf(h_str, "tmp/%09d.hb", i);
        h_file = string(h_str);
}
Run Code Online (Sandbox Code Playgroud)

MSa*_*ers 9

简单:提供足够的缓冲区.或者使用std::stringstream.


pax*_*blo 5

char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);
Run Code Online (Sandbox Code Playgroud)

这是未定义的行为.您正在尝试将大约17个字节的数据写入10字节数组:

  • tmp/ 是四.
  • %09d 将扩展到至少九个.
  • .hd 是三.
  • 字符串终止符\0是一个.

不要那样做.未定义的行为意味着功能的所有保证都是无效的.


事实上,如果你想成为一个真正体面的C++开发人员,你应该尽可能地避免遗留的东西.

在学习和需要在C和C++中运行的库代码时,这很好.但是,对于C++代码,使用该语言的非遗留部分要强得多.

以下程序显示了如何在不必恢复到旧版C的情况下执行此操作cstdio/stdio.h:

#include <iostream>
#include <iomanip>
#include <sstream>

using namespace std;

void make_name (unsigned int i, string &h_file) {
    stringstream ss;
    ss << "tmp/" << setw(9) << setfill('0') << i << ".hb";
    h_file = ss.str();
}


int main() {
    string s;
    make_name (42u, s);
    cout << s << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你会看到我已经改变你的方法签名来传递i值.那是因为我不确定将它作为const参考有什么好处.如果您确实找到了优势,请随时更改.