【发布时间】:2014-11-17 12:59:01
【问题描述】:
我有一个 C++ 跨平台程序(在 Linux 下用 g++ 编译,在 PC 下用 Visual Studio 编译)。该程序将行写入文本文件(使用<< 运算符和std::endl),但也可以从生成的文本文件中读回数据(使用std::getline)。
为了优化数据访问和节省内存,在读取数据文件时,我第一次读取它并将数据位置保存在我的程序中。当需要数据时,我稍后使用seekg 移动到特定位置并读取数据。
- 在 PC 上创建和读取文件工作正常。
- 在 Linux 上创建和读取文件工作正常。
- 但在 Linux 上创建文件并在 PC 上读取失败。
在 PC 下, seekg 有时无法相应地移动光标。我可以在下面的示例中隔离问题。它读取文件一次,保存第二行位置和值,然后移回保存的位置并再次读取该行。
#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>
int main()
{
std::fstream file;
file.open( "buglines.txt", std::ios_base::in );
if ( file.is_open() )
{
std::streampos posLine2;
std::string lineStr;
std::string line2Str;
int line = 1;
while ( std::getline( file, lineStr ) )
{
if ( line == 1 )
posLine2 = file.tellg(); // save line 2 position
if ( line == 2 )
line2Str = lineStr; // save line 2 content
++line;
std::cout << lineStr <<std::endl;
}
std::cout << "Reached EOF, trying to read line 2 a second time" << std::endl;
file.clear(); // clear EOF flag
file.seekg(posLine2); // move to line 2
std::getline( file, lineStr ); // read the line
assert( lineStr == line2Str ); // compare
}
return 0;
}
我在 Windows 上运行它。
- 如果
buglines.txt是在 Windows 下创建的(十六进制编辑器将行分隔符显示为 2 个字符0x0D 0x0A),它可以工作 (lineStr == line2Str)。 - 如果
buglines.txt是在Linux 下创建的(十六进制编辑器将行分隔符显示为1 个字符0x0A),它不起作用(lineStr 是空字符串)。即使 getline 循环运行良好。
我知道两个系统对 EOL 的处理方式不同,但由于我只是使用 getline 函数进行阅读,我希望它能够巧妙地工作......我错过了什么吗?
【问题讨论】:
-
你是否在使用 mingw 来制作 windows 二进制文件?
-
不,Visual Studio 2010 SP1
-
它也链接了哪个版本的 msvcrt?
-
msvcrt.dll: 7.0.7601.17744
-
该版本可能存在错误,至少根据旧的mingw page,尝试与更新的东西链接,VS 2010 应该与 10.0.something 捆绑在一起。
标签: c++ linux windows fstream eol