C++ 自定义读取产生垃圾

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

我正在实现自己的read函数,将文件中的内容读入缓冲区。它成功地读取了文件中的信息,但当我打印出信息时,输出中附加了垃圾空字节“\00\”。 因此,当我阅读“hi there”时,我的阅读输出可能是“hi\00\00\00th\00\00\00er\00e”。我不知道是什么原因导致了这种情况,非常感谢您的帮助。我不确定它是否重要,但每次2个字符后都会出现“\00\”

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或任何调试器吗