2012-08-10 73 views
1

Cstring :: Format在vsprintf.c第244行的visual studio 2008中導致調試斷言,其中「buffer too small」太小。CString :: Format()導致調試斷言

//inside the function. 

somefile.Open (//open for mode read) //somefile is CFile. 

char* buff = new [somefile.GetLength()]; 

somefile.Read ((void*)buff, somefile.GetLength()); 

CString cbuff; 
cbuff.Format ("%s",buff); //this line causes the debug assertion. 

//and so on 

任何想法爲什麼CString :: Format()導致「緩衝區太小」錯誤?這並不總是得到調試斷言錯誤。

回答

0

與「\ 0」 所以緩衝區大小串端將不足以

+0

是否意味着我必須做一些類似於buff.Format(「%s \ 0」,buff)?或者我應該在文件中讀取時將char *的大小增加1? – user1589128 2012-08-10 02:31:21

+0

對不起,有一個新手問題。但是我們假設字符緩衝區長度爲100個字節。如果我只讀取60個字節,緩衝區的最後40個字節是什麼? – user1589128 2012-08-10 02:35:02

+0

是的。最後的40個字節仍然存在。 我的意思是: char * buff = new [somefile.GetLength()+ 1];由於您將該文件作爲長字符串進行讀取,因此它應該有一個用於結尾的額外字節。 – silvesthu 2012-08-10 02:53:47

3

一種替代的解決方案是:

somefile.Open (//open for mode read) //somefile is CFile. 
int buflen = somefile.GetLength(); 

CString cbuff; 
somefile.Read ((void*)cbuff.GetBuffer(buflen), buflen); 
cbuff.ReleaseBuffer(); 

它直接讀入字符串緩衝區,而不是中間變量。 CString :: GetBuffer()函數會自動將額外的字節添加到您在分配「new char []」時忘記執行的字符串中。

+0

感謝您的回答。 – user1589128 2012-08-10 11:35:06

+0

這也有可能無法讀取整個文件。 – 2013-04-15 18:31:44

0

問題是,CFile::Read()不能保證它讀取儘可能多的數據,你所要求的。有時它讀取較少,並且保留沒有空終止符的緩衝區。你必須假設你在每個讀取的調用中只能得到一個字節。當一個不可讀的內存塊緊跟在你的緩衝區之後時,它也會崩潰。

您需要繼續閱讀文件,直到完成。此外,空終止符通常不會寫入文件,因此您不應該認爲它將被讀入,而是確保無論讀取什麼內容,您的緩衝區總是以空終止。

此外,您不應該使用文件大小作爲緩衝區大小;沒有理由認爲您可以一次全部讀取,文件大小可能很大或爲零。

你也應該避免手動內存管理,而是new[]/delete[],使用矢量,這將確保你不會忘記釋放緩衝,或者使用delete代替delete[],並且該內存甚至釋放在有例外的情況下。 (我不建議使用CStringCFile或者,對於這個問題,但這是另一個話題......)

// read from the current file position to the end of 
// the file, appending whatever is read to the string 
CString ReadFile(CFile& somefile, CString& result) 
{ 
    std::vector<char> buffer(1024 + 1); 
    for (;;) 
    { 
     int read = somefile.Read(&buffer[0], buffer.size() - 1); 
     if (read > 0) 
     { 
      // force a null right after whatever was read 
      buffer[read] = '\0'; 

      // add whatever was read to the result 
      result += &buffer[0]; 
     } 
     else 
     { 
      break; 
     } 
    } 
} 

注意,有一個在這個例子中沒有錯誤處理。