我想知道为什么给出以下内容:
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数组之前可能有一些元数据?
答案 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
格式说明符需要指向字符数组的初始元素的指针,而str1
和str2
为std::string