最近,我构建了一个看似简单的文本到字符字符串读取器,但它似乎会在文件末尾返回奇怪的文本。
所以这是我正在尝试读取的文件之一:
#version 330 core
in vec3 inputColour;
out vec4 outputColour;
void main()
{
outputColour = vec4(inputColour, 1.0f);
}
这是一个用 GLSL 编写的 OpenGL 着色器,仅供引用。但是,当我尝试“阅读”它时,它会返回:
请注意命令窗口末尾的四个 2
字符。当我尝试在运行时编译此着色器时,它会返回错误,其中包含一些原始文本中没有的字符。我创建了一个断点并进一步研究了它。我运行了该函数并打开了 Text-Visualiser,它返回了这个:
同样,文本末尾还有另外 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/