C++ 自定义读取产生垃圾
我正在实现自己的read函数,将文件中的内容读入缓冲区。它成功地读取了文件中的信息,但当我打印出信息时,输出中附加了垃圾空字节“\00\”。 因此,当我阅读“hi there”时,我的阅读输出可能是“hi\00\00\00th\00\00\00er\00e”。我不知道是什么原因导致了这种情况,非常感谢您的帮助。我不确定它是否重要,但每次2个字符后都会出现“\00\”C++ 自定义读取产生垃圾,c++,C++,我正在实现自己的read函数,将文件中的内容读入缓冲区。它成功地读取了文件中的信息,但当我打印出信息时,输出中附加了垃圾空字节“\00\”。 因此,当我阅读“hi there”时,我的阅读输出可能是“hi\00\00\00th\00\00\00er\00e”。我不知道是什么原因导致了这种情况,非常感谢您的帮助。我不确定它是否重要,但每次2个字符后都会出现“\00\” bool FileRead(int ptrBuffer, int bufferSize, int fid) { if (buf
bool FileRead(int ptrBuffer, int bufferSize, int fid)
{
if (bufferSize == 0)
{
DEBUG('p', "Cannot read zero bytes.\n");
machine->WriteRegister(2, -2);
return false;
}
char *buffer = (char *)malloc(sizeof(char *) * (bufferSize +1));
DEBUG('p', "Attempting to read %d bytes from file %d\n", bufferSize, fid);
// Read bytes from the file.
OpenFile* file = openFileTable[fid - FID_OFFSET];
if (file == NULL) {
DEBUG('p', "File does not exist!\n");
machine->WriteRegister(2, -4);
return false;
}
file->Read(buffer, bufferSize + 1);
int len = strlen(buffer);
DEBUG('p', "Read string %s with len %d\n", buffer, len);
buffer[len] = '\0';
strcpy(&machine->mainMemory[ptrBuffer], buffer);
machine->WriteRegister(2, len-1);
return true;
}
以下几行似乎很可疑:
file->Read(buffer, bufferSize + 1);
int len = strlen(buffer);
buffer[len] = '\0';
在这里,您试图通过使用strlen
获取所读取的缓冲区长度,该缓冲区明确要求传递的字符串被终止。然后将缓冲区作为字符串终止。如果缓冲区不包含要开始的终止符,则使用strlen
函数将导致未定义的行为
最有可能的是,Read
函数返回它读取的长度(通常是这样),这意味着如果该值是值长度,则需要使用该值(并且读取的字符数减少一个):
auto len = file->Read(buffer, bufferSize);
if (len > 0)
{
buffer[len] = '\0';
... (the rest of the code) ...
}
另外,请在打印前执行此操作。以下几行似乎非常可疑:
file->Read(buffer, bufferSize + 1);
int len = strlen(buffer);
buffer[len] = '\0';
在这里,您试图通过使用strlen
获取所读取的缓冲区长度,该缓冲区明确要求传递的字符串被终止。然后将缓冲区作为字符串终止。如果缓冲区不包含要开始的终止符,则使用strlen
函数将导致未定义的行为
最有可能的是,Read
函数返回它读取的长度(通常是这样),这意味着如果该值是值长度,则需要使用该值(并且读取的字符数减少一个):
auto len = file->Read(buffer, bufferSize);
if (len > 0)
{
buffer[len] = '\0';
... (the rest of the code) ...
}
另外,在尝试打印之前终止此操作。终止读取的字节不是空的,并且忽略实际读取的字节数:
file->Read(buffer, bufferSize + 1);
应该是:
int nr = file->Read(buffer, bufferSize + 1);
if(nr > 0) {
buffer[min(nr, bufferSize)] = '\0';
终止读取的字节不是null,也忽略实际读取的字节数:
file->Read(buffer, bufferSize + 1);
应该是:
int nr = file->Read(buffer, bufferSize + 1);
if(nr > 0) {
buffer[min(nr, bufferSize)] = '\0';
行中:
char*buffer=(char*)malloc(sizeof(char*)*(bufferSize+1))代码>您正试图将缓冲区大小的指针数量分配给字符。
您真正想要分配的是:
char*buffer=(char*)malloc(sizeof(char)*(bufferSize+1))代码>
或者更简单地说:
char*buffer=(char*)malloc(bufferSize+1)代码>
编辑:
顺便说一句,不熟悉“OpenRead”类等,所以不确定这些读取在引擎盖下做什么等。不确定它是否有返回值
另一件需要注意的事情是,假设->read方法在null终止字符串时与预期的方法类似,那么strlen确实会给出字符串中的字节数
您需要确保strcpy的目标为缓冲区内容留出空间。更安全的拷贝可能是使用strncpy(dst,src,len)调用。行中:char*buffer=(char*)malloc(sizeof(char*)*)*(bufferSize+1))代码>您正试图将缓冲区大小的指针数量分配给字符。
您真正想要分配的是:
char*buffer=(char*)malloc(sizeof(char)*(bufferSize+1))代码>
或者更简单地说:
char*buffer=(char*)malloc(bufferSize+1)代码>
编辑:
顺便说一句,不熟悉“OpenRead”类等,所以不确定这些读取在引擎盖下做什么等。不确定它是否有返回值
另一件需要注意的事情是,假设->read方法在null终止字符串时与预期的方法类似,那么strlen确实会给出字符串中的字节数
您需要确保strcpy的目标为缓冲区内容留出空间。更安全的方法是使用strncpy(dst、src、len)调用。这段代码有很多我们看不到的外部依赖项。我也看不到,我没有直接访问这些函数的权限,无法编辑它们。然而;我知道它们可以工作。这段代码有很多我们看不到的外部依赖项。我也不能,我没有直接访问这些函数的权限,也不能编辑它们。然而;我知道它们是有效的。谢谢,我测试了它,read确实返回了读取的字节数,我做了您建议的更改以及其他两个答案建议的更改,仍然得到了\00在原始代码中,您将分配:
(bufferSize+1)*4[对于32位系统)
(bufferSize+1)*8[对于64位系统]嗯……那么,下一步就是在文件->读取
行之后放入一个打印循环,看看它是否按预期填充了缓冲区。您知道如何使用gdb或平台上可用的任何调试器吗?最后,您是否尝试过更简单的方法:char*buffer=new char[bufferSize+1]
call?…等一下!你知道这个“文件->读取”是做什么的吗?任何文档-我现在怀疑可能是(除了上面提到的终止/strlen之类的其他问题)读取的是UNICODE字节?我对它们不是很熟悉,但我知道这是几个“多字节”中的一个字符集。这可能是一个线索。您在什么平台上运行,在什么操作系统版本和编译器下运行(后者可能不重要)。如果操作系统是Linux,请尝试“vi”在文件上查看它的外观,或者更好的是使用类似于util的hexedit查看源文件中的原始字节。谢谢,我测试了它,read确实返回了读取的字节数,我做了您建议的更改以及其他两个答案建议的更改,但仍然得到了\00在原始代码中,您将分配:
(bufferSize+1)*4[对于32位系统)
(bufferSize+1)*8[对于64位系统]嗯…好的,接下来的步骤是在文件->读取
行之后放入一个打印循环,看看它是否按预期填充了缓冲区。您知道如何使用gdb或任何调试器吗