sprintf和char与std :: string的数组

时间:2018-05-02 04:11:37

标签: c++

我想知道为什么给出以下内容:

int main()
{
    char buf[50];
    //char str1[] = "ahoy";
    //char str2[] = "matey";
    std::string str1 = "ahoy";
    std::string str2 = "matey";

    sprintf(buf, "%s %s\n", str1, str2);

    std::cout << buf;
    return 0;
}

当str1,str2是字符数组时,我得到ahoy matey的预期输出。但是当str1,str2是std :: string时,我得到了容量输出。它是否与char数组实际上只是那个有关,而std :: string在实际char数组之前可能有一些元数据?

4 个答案:

答案 0 :(得分:2)

你几乎做对了。 std::string除了字符串本身之外还包含额外信息,例如字符串的长度。实际上,字符实际上并不存储在字符串对象中。相反,字符串对象存储字符的内存地址,这些字符位于其他地方。

如果需要使用带char数组的函数,请使用c_str member function。您无法修改此函数返回的内容,如果字符串对象发生更改,结果可能会失效。

C输入/输出函数对C ++字符串一无所知,并尝试将数据解释为char数组,这就是为什么你会得到垃圾。如果你打开你的编译器警告(你真的应该这样做),编译器会警告你这个。

你应该坚持使用C ++字符串和输入/输出。 std::string提供了一个方便的overload for the + operator来连接字符串。如果您没有立即输出结果,请使用此选项。

newString = str1 + ' ' + str2;

您还可以使用多个<<,这可以防止使用+时发生的额外复制等内容。

std::cout << str1 << ' ' << str2 << '\n';

答案 1 :(得分:1)

代码会发出警告:

sudo sysctl -w net.ipv4.tcp_syn_retries=0

sprintf

prog.cc:15:18: warning: format '%s' expects argument of type 'char*',
but argument 3 has type 'std::__cxx11::string' {aka
'std::__cxx11::basic_string<char>'} [-Wformat=]

 sprintf(buf, "%s %s\n", str1, str2);
              ^~~~~~~~~

期待int sprintf( char* buffer, const char* format, ... );

因此,如果您真的想使用char* args将其首先转换为 c-string

std::string

<强> C ++ - 杂交

其他方式是使用sprintf(buf, "%s %s\n", str1.c_str(), str2.c_str());

stringstream

答案 2 :(得分:1)

应该是:  #include <sstream> std::stringstream ss; ss << str1 << " " << str2; std::cout << ss.str(); // ahoy matey 否则你将获得原始类数据 - 显然不是你想要的。但是,不要像这样混合使用C和C ++。一直使用sprintf(buf, "%s %s\n", str1.c_str(), str2.c_str());。 IOW,请考虑使用std::string作为附加内容。

答案 3 :(得分:1)

当你说,

sprintf(buf, "%s %s\n", str1, str2);

%s格式说明符需要指向字符数组的初始元素的指针,而str1str2std::string

The warning tells it all