我試圖在循環中逐行讀取std :: ifstream文件。在同一個循環中,我試圖找到兩個標籤,其中包含一個我希望作爲整體閱讀的塊。如何在文本模式下安全地混合使用std :: ifstream的tellg,seekg和read(*,n)方法
我想,我可以通過seekg跟蹤塊的開始和結束位置,並在找到兩個位置後使用read(*,end-start)來讀取塊。
但是,tellg返回流的位置,但由於文件已在文本模式下打開[所以我可以調用getline]並使用\ r \ n作爲行結束,參數「字符數」的ifstream's-read-method是指從\ r \ n轉換爲\ n後的數字,以便我讀取的字符數超過了我預期的n個字符,其中n是兩個標記之間的行數。
很明顯,有很多解決方法,但我正在尋找一個很好且直觀的解決方案。有什麼建議麼?
EDIT1 @ 130507: 我的目標是留在超速的標準庫流和青睞內存,我需要解析和處理兩部分,周邊部分和標籤之間的塊。
我希望有一些可用的東西,如在已打開的文本模式流中切換到二進制模式,或者有一些(基類)原始讀取方法不會像讀取或某些映射器那樣進行字符轉換允許在字符轉換之前和之後映射流指示之間的方法,但到目前爲止找不到任何東西。
下面是一些代碼:
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 {}
一個testfile的可能看起來如下:
some text
more text
starttag
much stuff on many lines
endtag
even more text
所以tellg和seekg得到在文本模式下真正棘手 –
文本模式下的流傾向於相對位置,而不是絕對的。執行'seekg(tellg())'會將當前流的位置替換爲未知位置。 它看起來有點低效率的,但我不知道會發生,如果不是什麼: 'testDataFileStream.seekg(cmdStartPos);' 你這樣做: '而(!testDataFileStream.tellg()= cmdStartPos)testDataFileStream.unget() ;' –