Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:C字符串到std:string_C++_String_Type Conversion - Fatal编程技术网

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

C++ C++;:C字符串到std:string,c++,string,type-conversion,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/

我正在尝试使用函数将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);
}

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

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;
}
#包括
#包括
#包括
使用名称空间std;
void make_name(无符号整数i、字符串和h_文件){
细流ss;

最好不要使用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());
}
std::字符串生成名称(无符号i)
{
std::ostringstream str;

str您所做的不仅仅是将c字符串转换为
std::string
。这可能就是问题所在。如果您认为X有问题,请编写一个执行X的测试用例,而不执行其他任何操作。天哪,gracious-您有一个10个字符的缓冲区,您正试图在其中打印16个字符加上NUL…“TWA永远不会有好结果。N曾经使用过
sprintf
,总是
snprintf(h_str,sizeof(h_str),“tmp/%09d.hb”,i)
更大的问题是,为什么它对-01起作用。它对
-O1起作用的原因与它在蓝月亮上可能起作用的原因相同。未定义的行为意味着任何事情都可能发生,这包括正确的行为。事实上,这是UB最阴险的事情之一,如果它总是通过发出一个短而尖锐的ele而失败,我更喜欢它自己对开发者生殖器官的冲击:-问题是,C++流对于很多用例来说都很糟糕,包括这一个……我们是不是在认真地提倡,乱流操纵者比等价代码< Prtff >好?(奖金问题:哪一个操作器是黏性的,如果有的话?如果我知道的话,见鬼去吧)由于我编写了一个类似于sprintf的函数来处理重新分配(如果需要的话),基本字符串格式变得简单了一个数量级,返回一个
std::string
,并用正确的gcc属性标记,以便它捕获任何类型错误-易于使用且类型安全。结束操纵器的愚蠢。@Matteo:我认为它们更好,因为它们显然可以防止缓冲区溢出:-),并且,如果您坚持使用
printf
,您将永远不会知道哪个是粘性的。奖金答案是,这里没有关系,因为粘性只适用于
ss
的单个短期实例。