我正在实现自己的读取函数,该函数将内容从文件读取到缓冲区中。 它成功地读取了文件中的信息,但是当我打印出信息时,它有垃圾空字节"\00\"附加到输出。因此,当我阅读"嗨,那里"时,我阅读的输出可能是"hi\00\00\00th\00\00\00er\00e"我不知道是什么原因造成的,感谢任何帮助。我不确定它是否重要,但"\00"每次出现在 2 个字符之后。
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 %dn", 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 %dn", buffer, len);
buffer[len] = ' ';
strcpy(&machine->mainMemory[ptrBuffer], buffer);
machine->WriteRegister(2, len-1);
return true;
}
以下几行似乎非常可疑:
file->Read(buffer, bufferSize + 1);
int len = strlen(buffer);
buffer[len] = ' ';
在这里,您尝试使用strlen
来获取读取的缓冲区的长度,该明确期望它传递的字符串被终止。然后,将缓冲区作为字符串终止。如果缓冲区一开始不包含终止符,则使用 strlen
函数将导致未定义的行为。
Read
函数很可能返回它已读取的长度(这是通常的(,这意味着如果它是值长度,则需要使用该值(并少读取一个字符(:
auto len = file->Read(buffer, bufferSize);
if (len > 0)
{
buffer[len] = ' ';
... (the rest of the code) ...
}
此外,在尝试打印之前执行此操作终止。
您不会以 null 终止读取的字节,也不会忽略实际读取的字节数:
file->Read(buffer, bufferSize + 1);
应该是:
int nr = file->Read(buffer, bufferSize + 1);
if(nr > 0) {
buffer[min(nr, bufferSize)] = ' ';
在行中: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( 调用。