我正在使用C ++ 14,根据我的理解,C ++ 11及更高版本中的std :: string以null字符结尾。 我无法理解为什么以下代码不起作用。
string a="your";
char b[5];
for(int i=0; a[i]! ='\0';i++)
b[i] =a[i] ;
cout<<b;
输出是: &#34; yourul&#34;(后跟2个随机字符)
答案 0 :(得分:6)
问题是您没有将终结器复制到目标阵列。相反,当你遇到它时你会结束循环(不复制它)。
在不知道用例或数组需求的情况下(很少有),不要使用手动复制。如果由于某种原因你无法使用,例如a.c_str()
或a.data()
甚至&a[0]
,然后使用strncpy
代替:
strncpy(b, a.c_str(), sizeof b - 1); // -1 to leave space for the terminator
b[sizeof b - 1] = '\0'; // And make sure string is terminated
请注意,std::string
对象中现有终结符的保证取决于所使用的C ++标准。在C ++ 11之前,无法保证字符串中存在终结符。在实践中它仍然(为了简单起见),但规范没有保证。
答案 1 :(得分:6)
所以std::string
确实具有向后兼容性,保证c_str()
和data()
返回的序列以0结尾,s[s.size()]
为您提供NUL。 (请注意,写入任何这些终结符都是未定义的行为。)
但是,您的代码有一个不同的错误:循环在遇到NUL时终止,并且不会将其复制到b
。因此b
的最后一个元素具有未指定的内容,并且读取它是未定义的行为。
不要自己写副本循环。使用strlen
或其中一个变体。或者更好的是,如果可能的话,根本不要使用可写的C风格的字符串。