2013-10-08 83 views
0

我有一個問題,我不知道如何解決它。 的問題是:C++垃圾在文件末尾

char * ary = new Char[]; 

ifstream fle; 
fle.open(1.txt, ios_base::binary); 
fle.seekg(fle.end); 
long count = fle.tellg(); 
fle.seek(fle.beg); 

現在的問題是: 文件1.txt的包含:你好世界!

當我執行:

ary = new char(count); 
fle.read(ary, count); 

充滿這樣的進制:世界,你好! @T#^ @ $ @ FF(垃圾)

該文件在ookay裏面沒有任何東西,只有上面的內容。

平臺:Win 7,VS 2012

不知道如何來解決這個問題。 (已解決)

(問題2) 現在我面臨另一個問題,fle.read有時閱讀比我給的尺寸更多。例如,如果我通過像fle.read(緩衝,1000),它在某些情況下結束(strlen的(緩衝)= 1500。我怎樣才能解決這個問題?

問候,

+0

它不是在文件中,這是您的分配內存的一部分。在做任何事之前嘗試將數組置空。即'ary = new char(count); memset(ary,0,count); fle.read(ary,count);',對於memset,如果你還沒有它,你還需要'#include '。 – bizzehdee

+2

爲什麼你打開二進制文件? – crashmstr

+0

並且count中有一個「o」。 – crashmstr

回答

3

我認爲你的問題不是你的數組包含垃圾,而是你忘記把null結束符放在最後,而你的print語句不知道什麼時候停止。您也寫了new char(count)而不是new char[count]。在第一種情況下,您只能實例化一個char,其值爲count,而在第二種情況下,您將創建一個count字符的緩衝區。

試試這個:

ary = new char[count+1]; 
fle.read(ary, count); 
ary[count] = '\0'; 
+0

謝謝你做了我想要的,對於我而不是增加緩衝區,我只是做了[count -1] ='\ 0',否則我將不得不改變接收緩衝區大小,如果沒有錯的話。 – nothing

+0

如果你做'ary [count-1] ='\ 0'',你將失去最後一個字節。 –

+0

是的,但我改變了閱讀大小爲-1,所以我可以保持該字節爲空。 現在我面臨着另一個問題,fle.read有時閱讀比我給的尺寸更多。例如,如果我像fle.read(目的地,1000)那樣通過,它在某些情況下結束1500.我該如何解決這個問題? – nothing

1

我們必須在這裏估計了一下,但最有可能這個歸結爲你調試的問題。緩衝區填寫正確,但錯誤地檢查其內容。

現在,ary被聲明爲char*,我懷疑,當你試圖檢查的內容ary你使用了一些打印方法,該方法需要一個以null結束的數組,但是你並沒有終止該數組,所以你有一個緩衝區溢出

如果您只打印了count個字符,那麼您就不會超支。如果你有空終止數組,也不會忘記爲空終止符分配一個額外的字符。

而不是使用原始數組和new,將緩衝區讀入std::string會更有意義。您應儘量避免使用以空字符結尾的字符串。在與非C++庫互操作時使用這些。

5

char [] - C中的字符串通常以null結尾。它們比所需的長一個字節,最後一個字節設置爲0x00。這是必要的,因爲C無法告訴數組的長度。

當您從文件中讀取二進制數據時,不會在字符串中讀入終止空字符。這意味着像printf這樣的函數對未知長度的char數組進行操作將輸出該數組以及在內存中發生的任何數據,直到它遇到空字符。

解決方案:分配char [] - 緩衝區比數據長度長一個字節,並手動將最後一個字節設置爲0

更好的解決方案:不要使用C風格的字符數組。做到面向對象的方式,並使用類std::string來表示字符串。

0

試試這個

ary = new char[count + 1]; 
fle.read(ary,count); 
ary[count] = '\0'; 

終止空字符不見了 - 它不是在文件中,你必須將它添加之後

0

你正在閱讀count字符爲一個文件,你必須分配一個額外的字符來提供字符串終止符(\0)。

ary = new char[count + 1]; 
ary[count] = '\0'; 
+0

這仍然只分配一個'char'。 (當然,他真正需要的是'std :: vector ary(count + 1);'。) –

+0

對。糾正。 –

2

大多數其他的答案錯過一個非常重要的一點: 當你做你ary = new char(count);分配與ASCII碼count一個符號初始化一個字符。 你應該這樣寫:ary = new char[count + 1];

+0

兩個尼特(因爲你不像所有其他人都有正確的答案):這裏沒有涉及ASCII。 'char'只是另一種小整數,並且用'count'的整數值初始化它(當然轉換爲'char')。而他應該寫的更多的是'std :: vector ary(count +1);'。 –

+0

@詹姆斯爲什麼沒有涉及ASCII?當你寫'char(32)'時,你會在裏面得到一個空間,因爲32是空間的ASCII碼,不是嗎? –

+0

輸出結果取決於輸出設備。你如何解讀它取決於你;如果你把它解釋爲一個字符,並且32是你正在使用的編碼中空間的代碼點(這可能是這種情況,即使ASCII本身已經死了,並且沒有在任何地方使用),那麼你會解釋它作爲一個空間。但最後,'char'是一個整數數據類型,它保存了整數值。在像'new char(count)'這樣的表達式中,沒有什麼可以說'count'應該被解釋爲一個代碼點,而不是一個普通的整數值。 –

2

好了,最明顯的問題是,你正在使用 new char(count),它分配一個char分配,與count初始化 。你可能試圖做的是new char[count]。你真正需要的是:

std::vector<char> arr(count); 
fle.read(&arr[0], count); 
在分配

或許count + 1,如果你想在緩衝區尾 '\0'

編輯:

既然你仍然有問題:fle.read永遠不會讀 超過要求。在 閱讀之後fle.gcount()返回什麼?

如果你這樣做:

std::vector<char> arr(count); 
fle.read(&arr[0], count); 
arr.resize(fle.gcount()); 

你應該有與char是 您已經閱讀完全數的向量。如果您希望將它們作爲字符串,則可以從arr.begin(), arr.end()構造一個 ,或者甚至可以使用std::string 而不是std::vector<char>開始。

如果你需要一個'\0'結尾的字符串(與 舊版軟件界面),那麼您只需建立矢量大小爲 count + 1,而不是count,並&arr[0]將是你 '\0'字符串。

不是嘗試在這裏使用new char[count]。 要做到這一點非常困難。 (例如,它將需要一個嘗試塊 和一個捕獲。)