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

时间:2015-07-27 07:27:14

标签: 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);
}

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:5)

char h_str[10];
sprintf(h_str, "tmp/%09d.hb", i);

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

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

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

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

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

以下程序显示如何执行此操作如果不必恢复cstdio/stdio.h中的旧版C内容:

#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;
}
  

顺便说一句,您会看到我已经更改了方法签名以按值传递i。那是因为我不确定将它作为const引用有什么好处。如果您 找到优势,请随时更改回来。

答案 2 :(得分:1)

最好是永远不要使用C字符串。

std::string make_name(unsigned i)
{
    std::ostringstream str;
    str << "tmp/" << std::setfill('0') << std::setw(9) << i << ".hb";
    return std::move(str.str());
}