看板 C_and_CPP 關於我們 聯絡資訊
直接回一篇好了 答案如同其他版友已經提供的,我只想補充嚴格說來 '\0' 也是 ASCII 字元 如果你的輸入檔案裡面原先有 '\0' 字元,你的方法「有可能」會失敗 舉例來說,如果輸入檔案 test.in 內容以十六進位顯示如下 68 65 6c 6c 6f 00 20 77 6f 72 6c 64 21 0a 以可顯示的 ASCII 字元就會如下: hello. world!. 第一個 . 是 '\0' 第二個 . 是 '\n' 顯示不出來我們暫時用 . 來代表 如果以你的讀檔方式,在 linux/g++ 4.8.2 上面只會讀到 hello, getline() 碰到檔案中的 '\0' 就停止了 上面提到的「有可能」是因為 text mode 開檔會做一些 ASCII 特殊字元的轉換, 至於會做哪方面的轉換,則要看作業系統和/或函數庫的實作而定, 或許以上的例子在 Windows/VC++ 上面跑會跳過 '\0' 繼續讀到檔案結尾也不一定 (我沒有在 Windows 上實驗過) 我自己不會太建議用 getline() 來讀整個檔案,畢竟它是一個字元一個字元去做 判斷,直覺上讀取速度會很慢,尤其檔案大的時候 版友提的 iterator 或 streambuf 的作法很簡潔漂亮,不過檔案大速度可能也會慢 (抱歉單純就事論事) 通常判斷完檔案的大小之後,一次將檔案讀取進來,速度通常會比較快 舉例來說,稍微小修一下你的程式: #include <iostream> #include <fstream> #include <string> using namespace std; int main(int argc, char **argv) { string str; ifstream fin(argv[1]); if(!fin) return 1; fin.seekg(0, ios::end); str.resize(fin.tellg()); fin.seekg(0, ios::beg); fin.read(&str[0], str.size()); fin.close(); cout << str; } 以上我在 linux 實驗可以,但據說有人用 text mode 使用 seekg(0, ios::end) 會失 敗,所以另一種作法也提供給你參考,就是使用 POSIX 的 stat() 函數和 struct stat 來取得檔案大小,再一次將檔案讀取進來 (在 Windows 下是 _stat() 函數和 struct _stat) 舉例: #include <sys/types.h> #include <sys/stat.h> #include <fstream> #include <string> #include <iostream> using namespace std; int main(int argc, char **argv) { ifstream fin(argv[1]); if(!fin) return 1; struct _stat s; string str; if(_stat(argv[1], &s)) return 1; str.resize(s.st_size); fin.read(&str[0], str.size()); fin.close(); cout << str; } 記得最前面的兩個 #include 上例我在 linux 實驗可以運作,於是直接把程式碼 stat 前面加底線變成 Windows 版本 沒意外的話應該可以用 以上提供給你參考 ※ 引述《out99 ( )》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : VC++ : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : 問題(Question): : 我想要一次將整個檔案讀進 std::string : 而不是用 while 一行一行讀取再 append string : 我直接使用 std::getline() 第三個參數 delim 丟入 '\0' 處理 : 測試過幾個檔案「看起來」沒有問題 : 我想問的是會不會有特殊情形導致這個方式讀出來的內容是錯誤的? : 直接假設「檔案的第一個 '\0' 字元就是整個檔案的結尾」是正確的嗎? : 謝謝 : 餵入的資料(Input): : 內容為 ASCII 字元,不包含其它特殊字元的文字檔。 : 預期的正確結果(Expected Output): : 錯誤結果(Wrong Output): : 程式碼(Code):(請善用置底文網頁, 記得排版) : #include <iostream> : #include <string> : #include <fstream> : using namespace std; : int main(int argc, char** argv) : { : string str; : ifstream fin(argv[1], ios::in); : if (fin.fail()) : return 1; : getline(fin, str, '\0'); : fin.close(); : cout << str; : return 0; : } : 補充說明(Supplement): -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.249.172.143 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1432320388.A.68E.html
out99: _stat在Windows下正常運作,而且速度也比較快 05/23 09:34
out99: 受教了,感謝! 05/23 09:34
out99: 我剛剛用stat在Windows下測試一樣能運作 05/23 09:47
out99: 我是用VS2013 05/23 09:48
Killercat: 我倒是沒有碰過ASCII檔案裡面夾\0的例子就是(抓頭 05/23 11:54
Killercat: 如果夾\0 我想fstream的<<應該會死光才對 05/23 11:55