c++ - 文件读取返回损坏的文件结尾

标签 c++ arrays string

最近,我构建了一个看似简单的文本到字符字符串读取器,但它似乎会在文件末尾返回奇怪的文本。

所以这是我正在尝试读取的文件之一:

#version 330 core
in vec3 inputColour;

out vec4 outputColour;

void main()
{
    outputColour = vec4(inputColour, 1.0f);
}

这是一个用 GLSL 编写的 OpenGL 着色器,仅供引用。但是,当我尝试“阅读”它时,它会返回:

Console Output

请注意命令窗口末尾的四个 2 字符。当我尝试在运行时编译此着色器时,它会返回错误,其中包含一些原始文本中没有的字符。我创建了一个断点并进一步研究了它。我运行了该函数并打开了 Text-Visualiser,它返回了这个:

Text Visualiser Image

同样,文本末尾还有另外 4 个字符,ýýýý


这是文本阅读器的代码:

std::ifstream inputFile("foo.txt", std::ios::in|std::ios::binary|std::ios::ate);
int inputFileSize;
char* buffer = "";

if (inputFile.is_open())
{
    inputFile.seekg(0, std::ios::end); //Set the cursor to the end.
    inputFileSize = (int)inputFile.tellg(); //Set inputFileSize to the position of the cursor.
    buffer = new char[inputFileSize]; //Create the buffer and set its size to the inputFileSize.
    inputFile.seekg(0, std::ios::beg); //Move the cursor to the beginning.
    inputFile.read(buffer, inputFileSize); //Read the file from the beginning.
    inputFile.close(); //Close the file
}

我的猜测是它可能与行尾读取不当有关。但是,我已经用 Notepad++ 和内部 Visual Studio 编辑器编写的文件进行了测试,两者都给了我相同的结果。

我确实找到了“解决方法”。也就是说,这是一种非常糟糕的做法。基本上,您可以将 [FILEEND] 和您阅读的任何文本文件的末尾放在一起。虽然代码允许 [FILEEND] 或根本没有,但代码需要 [FILEEND] 才能正确读取文件。

char* fileend = std::strstr(buffer, "[FILEEND]"); //Find [FILEEND].
int actualfilelen = fileend != NULL ? std::strlen(buffer) - std::strlen(fileend) : std::strlen(buffer); //Get the length of the main content of txt file. 
//If there is no [FILEEND] then return the size of the buffer without any adjustments.
char* output = new char[actualfilelen + 1]; //Create new string with the length of the main content of txt file.
std::strncpy(output, buffer, actualfilelen); //Copy main content of buffer to output.
output[actualfilelen] = '\0'; //Add escape sequence to end of file.
delete(buffer); //Deletes the original buffer to free up memory;

然后我们只返回 output 变量。 我不想在我的文件末尾使用 [FILEEND] 关键字(?),因为它们会立即变得不那么便携。一两个带有 [FILEEND] 的文件可能没问题,但如果我有数百个文件想在另一个项目中使用,它们都将带有 [FILEEND]

最佳答案

您没有确定缓冲区是 \0 终止的。使其成为inputFileSize+1,读取完毕后终止。

std::strlen(buffer) 这样的函数期待它。如果你试图在没有提供长度的情况下在任何地方使用它,它会继续读取缓冲区的末尾。

此外,您需要delete[] buffer,因为它是用new[]分配的

关于c++ - 文件读取返回损坏的文件结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38386741/

相关文章:

c++ - 如何使用 3d 渲染缩放 2d 世界?

c++ - C++ 中的错误共享

python - Numpy 随机选择生成具有所有唯一值的二维数组

java - int[][] 数组不工作 - java applet

c++ - 从输入缓冲区读取

java - ArrayList 无法使用 (String[])list.toArray() 转换为字符串数组。为什么?

c++ - Qt - 更新 PaintGL

php - 使用 jQuery 将多维数组转为表格

javascript - 我想返回一个对象,但我得到一个字符串

c++ - 比较字符串在 mingw 和 ubuntu gcc 上表现不同