2013-05-18 50 views
0

我從std :: fstream類中得到了tellg()函數的問題。通常它應該返回輸入流中當前字符的位置。但是,它對我來說很奇怪。下面是一些簡短的示例代碼:tellg()函數的奇怪行爲C++

#include <iostream> 
#include <fstream> 

using namespace std; 

int main(void) { 
char c; 
ifstream czytaj; 
czytaj.open("test_file.txt"); 

cout << czytaj.tellg() << endl;  //is 0 should be 0 
czytaj.peek();      //is 0 should be 0 
cout << czytaj.tellg() << endl;  //is 2 should be 0 !! 
czytaj.get(c);      //is 3 should be 3 
czytaj.get(c);      //is 4 should be 4 
cout << czytaj.tellg() << endl;  //is 6 should be 4 !! 

int r; cin >> r; 
return 0; 
} 

雖然txt文件看起來像如下:

abcdefghij 
kturjbkfvd 

編譯後,我得到的輸出,如:

0 
2 
6 

首先使用所以tellg()的作品正確地說,它返回位置0作爲文件的開始。不幸的是,每次下一次使用都會像增加+2這樣的位置。結果我得到了從流中提取的字母'c'和'd'。無論所以tellg()和PEEK()應該不會改變位置,所以我應該有字母「A」和「B」,而正確的結果應該是:如果我使用的編碼

0 
0 
2 

這樣的事情發生ANSI在txt文件中。當我將它更改爲Unicode時,它的工作原理應該如此。另外,如果我使用ANSI和另外的二進制模式ios :: binary,它也可以正常工作。奇怪的事實是,在我的另一臺電腦上,即使使用ANSI並且沒有使用ios :: binary,它也能正常工作。爲什麼會發生?

編輯:忘了提及一個非常重要的事實。如果我從這個示例代碼中刪除所有包含tellg()的行,提取是正確的 - 我得到字母'a'和'b'。

+0

對我的作品與G ++ 4.7.2的libstdC++ 4.7.2。你使用的是什麼編譯器/庫? –

+0

它可能是一個在前面帶有BOM標記的UTF-X編碼文件。使用十六進制編輯器轉儲文件並向我們顯示內容。在Linux上嘗試:'od -t x1 -t c test_file.txt' –

+0

您的輸入文件是否包含除'abcdefgh'以外的任何其他符號?也許換行符或其他東西?它可能是文件是Unicode(UTF-16)? – Inspired

回答

1

tellg()告訴你文件中下一個「get」位置在哪裏。由於Windows中使用CR + LF('\r','\n')作爲換行符的文件有兩個字符作爲換行符,其中C++(和C)標準要求換行符爲LF '\n'作爲單個字符,所以當程序讀取CR + LF序列中,C運行時將其計爲一個字符,但您從中獲得下一個字符的文件位置向前是兩個步驟。

+0

對了,但我不明白的是,爲什麼第二次使用tellg()突然返回2而不是0,而流完全沒有移動,只是在同時偷看。在這兩個tellg()使用之間沒有提取字符。 – Givi

+0

不確定。我會說這可能是一個錯誤。 –

+0

它更復雜,交配。 Cuz每個組合像peek()+ tellg()「增加」2的位置,這真的很荒謬。 – Givi

0

也有同樣的問題。嘗試讀取FILESTREAM二進制:

czytaj.open("test_file.txt",ios::binary); 

它幫助我