2013-08-22 43 views
3

我正在構建一個程序,它接收串行數據並將其保存到文件中。每行數據都有時間戳。在此代碼中,時間戳的數據行是s。這個fwrite爲什麼寫垃圾?

string s = get_timestamp(); 
cout << "input string named s is: " << s << "\n"; 
numChars = sizeof(s); 
cout << "size is: " << numChars << "\n"; 
fwrite(&s, sizeof(char) , numChars , DATA_LOG); 

報表的打印輸出

00000.27m,379named s is: 20130822.1141,00000.26m,379 
size is: 28 

你可以看到,由於某種原因,「輸入字符串命名的」似乎被覆蓋。雖然我不知道它爲什麼會發生,但這並不是我最關心的問題。)

我的主要問題是我的fwrite將垃圾保存到文件。你可以看到numChars和字符串是正確的。我試着用相同的垃圾結果代替「& s」,「static_cast(& s)」。有任何想法嗎?

+0

我們是否爲這個'stdout'假設'DATA_LOG'?你是否熟悉術語「buffered io」? – WhozCraig

+1

's'的類型是什麼? – interjay

+0

我把它聲明爲'FILE * DATA_LOG;'。它包含正在寫入的文件路徑。我相信這個問題不在'DATA_LOG'中,因爲我之前已經正確寫入了它。緩衝IO?是否像將IO存儲到緩衝區一次寫入所有內容? – user2619824

回答

4

首先,我懷疑s包含一些carriage returns。這會導致光標移動行的開頭,並進一步輸出覆蓋已經打印的內容。要查看打印的實際字符,請將程序輸出重定向到一個文件,然後使用十六進制編輯器/查看器(例如xxd)檢查結果。

其次,sizeof(s)不是確定std::string長度的正確方法。改爲使用s.length()。這就是爲什麼numChars不正確。

最後,將字符串寫入文件,使用:

fwrite(s.data(), sizeof(char) , s.length() , DATA_LOG); 
+0

「換行符」在不同的操作系統中也有所不同。在每行的末尾嘗試使用「\ r \ n」,以防萬一。 – Roboprog

+2

@Roboprog:以防萬一?你爲什麼要在只使用'「\ n」'作爲行結束符的系統上將'\ r \ n「'寫入文件?如果文件以文本模式打開,'fwrite'會將數據中的任何換行符轉換爲系統的行尾表示。 –

+0

@KeithThompson:無論您通過「cat」或「type」查看文件的操作系統如何,光標都會移到左邊距並放下一條線。文字模式應該照顧它,但偏執狂可能是有用的。 – Roboprog

0

sizeof(s)確實應該strlen(s)wcslen(s)

或者,如果你使用的std::basic_string<>.length()會給你的長度和.c_str()會給你char string pointer,不&s這是指向實際的對象。

所以儘量

if(!s.empty()){ 
    fwrite(s.c_str(), sizeof(s.front()), s.length(), DATA_LOG); 
} 
1

std::string s的文件將是這個樣子:

fwrite(s.c_str(), 1, s.size(), DATA_LOG); 

可能還有其他的問題,與您的數據,查看控制檯打印輸出,但我不確定沒有看到調試器或類似的實際數據。

+0

@MooingDuck:你的意思是找到字符串的基本類型的大小? sizeof(s [0])在這種情況下? –

+0

'sizeof(s)',即'sizeof(std :: string)',是無關緊要的。 (請注意,std :: string對象的大小不會隨着它所管理的字符序列的長度而改變;它全部是內部簿記數據。) –