C++ 动态分配的C样式字符串的字符数是否超过给定长度?

C++ 动态分配的C样式字符串的字符数是否超过给定长度?,c++,arrays,file,c-strings,C++,Arrays,File,C Strings,我使用动态C样式字符串从文件中读入数据,但由于某种原因,当我使用给定长度动态分配C样式字符串时,它会附带四个额外字符,可以使用strlen()看到这些字符。这些空白处的垃圾被添加到读入字符串的末尾,并显示在cout上。究竟是什么原因导致了这一问题,我该如何解决 C样式字符串在代码开头声明,并在此之前使用一次。在此之前使用它的时间也太长,但在这种情况下,它不会在末尾添加额外的信息。使用后,它将被删除,直到此时才再次使用。我很困惑,因为我以前没有发生过这种情况,也没有遇到过问题 // Length

我使用动态C样式字符串从文件中读入数据,但由于某种原因,当我使用给定长度动态分配C样式字符串时,它会附带四个额外字符,可以使用
strlen()
看到这些字符。这些空白处的垃圾被添加到读入字符串的末尾,并显示在
cout
上。究竟是什么原因导致了这一问题,我该如何解决

C样式字符串在代码开头声明,并在此之前使用一次。在此之前使用它的时间也太长,但在这种情况下,它不会在末尾添加额外的信息。使用后,它将被删除,直到此时才再次使用。我很困惑,因为我以前没有发生过这种情况,也没有遇到过问题

// Length read as 14, which is correct
iFile.read(reinterpret_cast<char *>(&length), sizeof(int)); 

tempCstring = new char[length]; // Length still 14
cout << strlen(tempCstring); // Console output: 18

// In tempCstring: Powerful Blockýýýý
iFile.read(reinterpret_cast<char *>(tempCstring), length);

// Custom String class takes in value Powerful Blockýýýý and is 
// initialized to that
tempString = String(tempCstring);

// Temp character value takes in messed up string
temp.setSpecial(tempString); 
delete[] tempCstring; // Temp cString is deleted for next use
//长度读取为14,这是正确的
iFile.read(重新解释类型和长度),sizeof(int));
tempCstring=新字符[长度];//长度仍然是14

cout每当您在字符串末尾看到垃圾时,问题几乎总是缺少终止符。每个C样式字符串以一个值为零的字节结尾,拼写为
'\0'
。如果您自己没有放置一个,则标准库会一直读取内存中的字节,直到它在内存中看到随机的
'\0'
。换句话说,数组的读取超出其边界

使用
memset(tempCString,0,length)
在分配后将内存归零。然而,这并不是最合理的解决方案,因为它掩盖了真正的问题。向我们展示使用此代码的上下文。然后,我将能够说明在算法中需要插入空终止符的位置:
tempCString[I]=0
,或者类似的内容。尽管如此,从你发布的内容来看,我可以告诉你,你需要再分配一个角色来为终结者腾出空间


也,既然你使用C++,为什么不使用<代码> STD::String < /C>?它避免了这类问题。

每当您在字符串末尾看到垃圾时,问题几乎总是缺少终止符。每个C样式字符串以一个值为零的字节结尾,拼写为
'\0'
。如果您自己没有放置一个,则标准库会一直读取内存中的字节,直到它在内存中看到随机的
'\0'
。换句话说,数组的读取超出其边界

使用
memset(tempCString,0,length)
在分配后将内存归零。然而,这并不是最合理的解决方案,因为它掩盖了真正的问题。向我们展示使用此代码的上下文。然后,我将能够说明在算法中需要插入空终止符的位置:
tempCString[I]=0
,或者类似的内容。尽管如此,从你发布的内容来看,我可以告诉你,你需要再分配一个角色来为终结者腾出空间


也,既然你使用C++,为什么不使用<代码> STD::String < /C>?它避免了这类问题。

您需要
length+1
来允许空终止符,实际上您必须空终止它。无关:小心使用术语CString。我已经开始调用以null结尾的字符数组c-strings来防止混淆,因为我太懒了,不能反复键入以null结尾的字符数组。
iFile.read(reinterpret_cast(&length),sizeof(int))
考虑到
length
是一个
int
?@empoweredev在旁注中,当将字符串写入文件时,应该调用
getStr()
一次并将值缓存到局部变量中,然后在计算
length
和调用
write()
时可以使用该变量。不,在将
长度
写入文件时,不应为空终止符添加+1(除非您实际将空终止符写入文件)。@KillzoneKid代码以
格式将字符串存储在文件中,即先写入
长度
,然后写入字符,在读取字符串时也是如此,它先读取
长度
,然后读取字符。您需要
长度+1
来允许空终止符,实际上您必须将其空终止。无关:注意术语CString。我已经开始调用以null结尾的字符数组c-strings来防止混淆,因为我太懒了,不能反复键入以null结尾的字符数组。
iFile.read(reinterpret_cast(&length),sizeof(int))
考虑到
length
是一个
int
?@empoweredev在旁注中,当将字符串写入文件时,应该调用
getStr()
一次并将值缓存到局部变量中,然后在计算
length
和调用
write()
时可以使用该变量。不,在将
长度
写入文件时,不应为空终止符添加+1(除非您实际将空终止符写入文件)。@KillzoneKid代码以
格式将字符串存储在文件中,即先写入
长度
,然后写入字符,在读取字符串时也是如此,它先读
长度
然后读字符。啊,伙计,现在我觉得自己很笨。我认为空终止符不是问题所在,因为它使cstring比我发送的值长。我在我的文件读取中修复了它,这样一个被添加到长度中,空终止符被放在空的空间中,现在可以正常工作了。非常感谢您帮助我,先生!至于我为什么不使用字符串,这是一个学校项目,我被要求编写自己的字符串类来使用。我假设这意味着我不应该使用内置的string类,所以我一直在使用cstring。这肯定会让事情变得更简单。@edev你已经被赋予了权力。如此之多以至于你可以随意开枪打自己的脚。这些怎么办
// Length set to the length of the cString, m_special
length = strlen(chars[i].getSpecial().getStr());

// Length written to file. (Should I add 1 for null terminator?)
cFile.write(reinterpret_cast<char *>(&length), sizeof(int));

// String written to file
cFile.write(reinterpret_cast<char *>(chars[i].getSpecial().getStr()), length);