我正在尝试使用std :: ifstream循环逐行读取文件。在同一个循环中,我试图找到两个标记,这些标记包含我想要整体读取的块。
我认为,我可以使用seekg跟踪块的起始和结束位置,并在找到两个位置后使用read(*,end-start)来读取块。
然而,tellg返回流位置,但由于该文件已在文本模式下打开[以便能够调用getline]并使用\r\n作为行末,请注意ifstream的read方法的“字符数”参数是指换行符从\r\n转换为\n后的数量,因此我正好比预期多读入n个字符,其中n是两个标记之间的行数。
显然,有许多变通方法,但我正在寻找一种漂亮而直观的解决方案。 有什么建议吗?
EDIT1@130507: 我的目标是保持std lib流,注重内存而不是速度,并且需要解析和处理两部分,即周围的部分和标记之间的块。
我希望有一些可用的东西,例如切换到已打开的文本模式流的二进制模式,或者具有某些(基类)原始读取方法,它不像read那样进行字符转换,或者一些映射器方法,允许在字符转换之前和之后在流索引之间进行映射,但迄今为止找不到任何东西。
这里是一些代码:
一个测试文件可能看起来像以下内容:
我认为,我可以使用seekg跟踪块的起始和结束位置,并在找到两个位置后使用read(*,end-start)来读取块。
然而,tellg返回流位置,但由于该文件已在文本模式下打开[以便能够调用getline]并使用\r\n作为行末,请注意ifstream的read方法的“字符数”参数是指换行符从\r\n转换为\n后的数量,因此我正好比预期多读入n个字符,其中n是两个标记之间的行数。
显然,有许多变通方法,但我正在寻找一种漂亮而直观的解决方案。 有什么建议吗?
EDIT1@130507: 我的目标是保持std lib流,注重内存而不是速度,并且需要解析和处理两部分,即周围的部分和标记之间的块。
我希望有一些可用的东西,例如切换到已打开的文本模式流的二进制模式,或者具有某些(基类)原始读取方法,它不像read那样进行字符转换,或者一些映射器方法,允许在字符转换之前和之后在流索引之间进行映射,但迄今为止找不到任何东西。
这里是一些代码:
std::ifstream testDataFileStream;
testDataFileStream.open(testDataFileName, std::ios_base::in);
testDataFileStream.unsetf(std::ios::skipws); // No white space skipping
if (testDataFileStream) {
std::string line;
while (getline(testDataFileStream, line))
if (line == "starttag")
break;
if (line == "starttag")
{
std::ifstream::pos_type cmdStartPos = testDataFileStream.tellg();
std::ifstream::pos_type cmdEndPos;
while (getline(testDataFileStream, line))
if (line == "endtag")
break;
else
cmdEndPos = testDataFileStream.tellg();
if (line == "endtag")
{
std::streamsize nofBytesToRead = cmdEndPos - cmdStartPos;
// now, one possible workaround follows, however, it's obviously quite lame
testDataFileStream.close();
testDataFileStream.open(testDataFileName, std::ios_base::in | std::ios::binary);
testDataFileStream.seekg(cmdStartPos);
std::string cmdsString;
cmdsString.resize(nofBytesToRead+1);
testDataFileStream.read(&cmdsString[0], nofBytesToRead);
} else {}
} else {}
testDataFileStream.close();
} else {}
一个测试文件可能看起来像以下内容:
some text
more text
starttag
much stuff on many lines
endtag
even more text
seekg(tellg())
将会将当前流的位置移动到未知的位置。 这样做可能看起来有点低效,但我想知道如果你这样做会发生什么:while (testDataFileStream.tellg() != cmdStartPos) testDataFileStream.unget();
- Thanasis Papoutsidakis