我正在使用动态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
写入文件时
// 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);
答案 0 :(得分:6)
每当在字符串末尾看到垃圾时,问题几乎总是缺少终结符。每个C风格的字符串都以一个值为零的字节结尾,拼写为'\0'
。如果您自己没有放置,则标准库将继续读取内存中的字节,直到它在内存中看到随机的'\0'
为止。换句话说,数组的读取超出其范围。
使用memset(tempCString,0,length)
可以在分配后将内存清零。但是,这不是最合理的解决方案,因为它涵盖了地毯下的实际问题。向我们展示使用此代码的上下文。然后,我可以说出您需要在算法的哪个位置插入空终止符:tempCString[i] = 0
或类似的东西。尽管如此,从您发布的内容来看,我可以告诉您需要再分配一个字符来为终止符腾出空间。
此外,由于您使用的是C ++,为什么不使用std::string
?避免了此类问题。