2013-04-28 63 views
0

我正在嘗試編寫一些代碼來讀取文件並提取它的位並將它們保存爲變量。任何方式擺脫istream結束時的空字符得到?

下面是相關代碼:

char address[10]; 

ifstream tracefile; 
tracefile.open ("trace.txt"); 
tracefile.seekg(2, ios::beg); 
tracefile.get(address, 10, ' '); 
cout << address; 

文件的內容:(只第一行)

R 0x00000000 

我遇到的問題是地址錯過最後的「0」因爲它在那裏放了一個/ 0字符,我不知道如何解決這個問題?因此它輸出:

tracefile.seekg(2, ios::cur); 

它似乎沒有工作,因此爲什麼我把它改爲IOS ::求只是爲了嘗試並獲得

0x0000000 

我也有問題一些工作,雖然顯然,一旦我嘗試讀取多行後,將無法使用。

任何幫助,將不勝感激。

+0

如何使用拆分字符串? http://stackoverflow.com/questions/236129/splitting-a-string-in-c – user1732445 2013-04-28 16:04:58

+0

使數組大小11個 – Praetorian 2013-04-28 16:06:06

回答

0

使緩衝區更大,以便您可以讀入整個輸入文本,包括終止'\0'。或使用std::string,它沒有預先確定的大小。

+0

謝謝,我沒有做到這一點,但隨後介紹了與下位的問題我需要編寫代碼,將地址與數組中的條目進行比較(我正在編碼緩存模擬器),因爲會有一個額外的字符,我不想要,我應該提到在OP 。 – GeorgeStorm 2013-04-28 16:16:38

+0

讀入C風格的文本緩衝區在輸入末尾放置一個「\ 0」。這就是C字符串的工作原理。如果你對「\ 0」後綴不感興趣,可以忽略它。 – 2013-04-28 16:19:44

+0

@ user2329442爲什麼它會導致地址比較問題。你有一個字符串。根據定義,C風格的字符串是以''\ 0''結尾的;如果沒有''\ 0'',你會對你的變量做任何事情都會有非常嚴重的問題(即像'strcmp'這樣的函數將不起作用)。 – 2013-04-28 16:22:55

3

ifstream::get()將嘗試產生一個以空字符結尾的C字符串,但您尚未提供足夠的空間。

您可以:

  1. 分配char address[11];(或更大)持有空終止字符串,長度超過9個字符。
  2. 改爲使用ifstream::read()來讀取沒有空終止符的10個字節。

編輯:

如果你想有一個緩衝區,可以動態佔線路長度,使用std::getlinestd::string

std::string buffer; 
tracefile.seekg(2, ios::beg); 
std::getline(tracefile, buffer); 

編輯2

如果你只想讀下一個空格,使用:

std::string buffer; 
tracefile.seekg(2, ios::beg); 
tracefile >> buffer; 
+0

正如我對皮特說,它放大解決了這個問題,但我認爲會介紹他人:( 我會看看:: ifstream的閱讀()謝謝:) – GeorgeStorm 2013-04-28 16:16:57

+1

@ user2329442 _not_提供尾隨'「\ 0」如果你把它當作一個字符串來處理,會給下游帶來更多的問題。如果你想把輸入視爲一個字符串(顯然你這麼做了,因爲這就是'char []'通常意義上的意思),那麼你必須確保最後還有一個額外的'''0' _或_使用'std :: string'(通常是首選的解決方案)。 – 2013-04-28 16:25:45

+0

目標是讓程序讀取地址,檢查緩存是否包含該地址的數據,如果是,則讀取它,如果不是,則轉到主內存並將其複製到緩存中(緩存和主內存是數組)。所以'地址'將與'cache'數組中每個條目的地址變量進行比較。 我很快嘗試使地址字符串而不是char [],但後來讀/不喜歡它? – GeorgeStorm 2013-04-28 16:33:24

0

有你的代碼的幾個問題。首先是 seekg(2, ios::beg)是未定義的行爲,除非在二進制模式下打開流 (不是你的)。它將在Unix下工作 ,並根據文件的內容,它 可能在Windows下工作(但它也可能會將您發送到 錯誤的地方)。在其他一些系統上,它可能會系統地失敗,或者做其他任何事情。您無法可靠地將 查找到文本流中的任意位置。

第二個是,如果你想讀的正好10個字符, 你需要的功能是istream::read,而不是 istream::get。另一方面,如果您想讀取 下一個空格,將>>轉換爲字符串將效果最佳。 如果你想打電話>>之前限制提取到最大 的字符數,設置寬度:

std::string address; 
// ... 
tracefile >> std::setw(10) >> address; 

這樣就避免了'\0'所有問題,等等

最後,當然,你需要錯誤檢查。你應該 可能檢查是否開放做任何其他 之前成功了,你一定要檢查使用結果之前讀取是否成功 。 (正如你所編寫的代碼,如果 打開的任何原因而失敗,你有不確定的行爲。)

如果你正在讀多行,當然,最好的解決辦法 通常是使用std::getline閱讀每行成 字符串,然後解析該字符串(可能使用 std::istringstream)。這防止 進入錯誤狀態的主要流如果在線路的格式錯誤,以及 它在這樣的情況下提供自動再同步。