2012-08-28 142 views
2

我使用std :: getline()從一個文本文件逐行讀取。但是,第一次調用getline就是讀取整個文件!我也試過明確地將分隔符指定爲'\ n'。任何想法,爲什麼這可能會發生?C++ getline讀取整個文件

我的代碼:

std::ifstream serialIn; 
... 
serialIn.open(argv[3]); 
... 
std::string tmpStr; 
std::getline(serialIn, tmpStr, '\n'); 
// All 570 lines in the file is in tmpStr! 
... 
std::string serialLine; 
std::getline(serialIn, serialLine); 
// serialLine == "" here 

我使用Visual Studio 2008中的文本文件有570線(我看它在記事本++ FWIW)。

編輯:我通過使用記事本++來將輸入文本文件中的行結尾轉換爲「Windows」行結尾來解決此問題。該文件在每行的末尾用'\ n'編寫,使用C++代碼。爲什麼getline()需要Windows行尾(\ r \ n)?這是否與字符寬度或Microsoft實現有關?

+0

你能請張貼文件的前10行。 –

+0

我很確定getline()默認爲''\ n''作爲分隔符。我不明白爲什麼回車會影響它。 – Rapptz

+1

標準I/O庫函數讀取和寫入平臺的行結束符。針對Windows C或C++運行庫構建的程序因此期望Windows行結束(令人震驚!)。 – jamesdlin

回答

6

只是猜測,但你的文件可以有Unix行結束,你在Windows上運行?

+1

+1只是爲了解釋...在UNIX/Linux上,單個換行字符(ASCII代碼10)劃定了行,而在Windows上,回車(13)和換行符都是預期的。因此,如果您的文件只有換行符,則可能無法通過C++將其識別爲行分隔符,即使某些編輯器會識別它們並以預定換行符顯示文件內容。 –

+0

我不明白的是,爲什麼getline()在它的文檔說它單獨使用'\ n'(Unix)行分隔符時需要Windows行結束符(\ r \ n)?此外,我明確將分隔符設置爲'\ n'來確保。你是否說文檔和它的真實工作之間確實存在差異?感謝您的答覆。 – voxoid

2

你混淆與換行符你在代碼('\n')看到實際行結束表示爲平臺(的回車(CR)和換行(LF)字節的某種組合)。

標準I/O庫函數自動將您的平臺的行結束符轉換爲文本模式流的概念換行符(默認設置)。請參閱comp.lang.c FAQ中的What's the difference between text and binary I/O?。 (雖然這是來自C FAQ,但這些概念也適用於C++)。由於您在Windows上,默認情況下,標準I/O函數將新行寫爲CR-LF,並且在讀取時期望換行符使用CR-LF。

如果你不想這些轉換完成,並希望看到原始的,純粹的數據,那麼你應該將你的流設置爲二進制模式。在二進制模式下,\n僅對應於LF,而\r對應於僅CR。

在C語言中,你可以通過"b"的標誌之一fopen指定二進制模式:

FILE* file = fopen(filename, "rb"); // Open a file for reading in binary mode. 

在C++:

std::ifstream in; 
in.open(filename, std::ios::binary); 

或:

std::ifstream in(filename, std::ios::binary);