2016-11-17 27 views
0

我正在學習MFC庫CFile類,並且使用Write方法將數據寫入文件時出現問題。當我通過字符數組作爲參數,它工作完全正常:寫的是當使用Write成員將CString寫入CFile時每個字符之後的空值

char c[] = "Hello!"; 
int size = sizeof(c)/sizeof(c[0]); 
myFile.Write(c, size) 

字符到文件:

Hello! 

但是,當我試圖通過CString對象作爲參數:

CString cS("Hello"); 
myFile.Write(cS, cS.GetLength()); 

我收到:

H e l 

我也試過:

CString cS("Hello"); 
LPWSTR c = cS.GetBuffer(); 
myFile.Write(c, cS.GetLength()); 
cS.ReleaseBuffer(); 

但是輸出和上面一樣。什麼可能是因爲轉換?這是否發生,因爲文本以寬字符存儲?

+2

使用'CStringA',而不是'CString'。 ASCII範圍中的寬字符由一個字節的ASCII和一個空字節組成。 –

回答

3

問題:

CFile::Write第二個參數是該函數將來自所述第一參數(緩衝器)傳送的字節數。您傳遞的是cS.GetLength(),它寧願傳遞字符串中的字符數,這與字符串本身可能組成的字節數不同。

解決方案:

您應該更改該字符串寫入文件,像這樣的行:

myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR)); 

sizeof(TCHAR)將產生基於如果您正在構建對Unicode不同數量或MBCS。這是因爲TCHAR被定義爲wchar_t爲Unicode版本,並作爲char爲MBCS版本。因此,字符串的長度TCHAR的大小乘將總是等於字符串組成的字節數,無論如果您正在爲Unicode或沒有的。

其他注意事項:

你沒有理由罵GetBuffer()ReleaseBuffer()在這裏,任何責任。

這一點不是主要的,但CFile::Write函數以const void *作爲其第一個參數。所以,你應該寧願被您鑄造CStringLPCTSTR(如果你使用Unicode或MBCS建設這將自動評估,以LPCWSTR或基於LPCSTR)。

最後一件事:用_T()宏包裝字符串文字很好,這樣就可以編譯Unicode和MBCS而不必更改代碼。

應用所有的變化,你的整個代碼將是這個樣子:

CString cS(_T("Hello")); 
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR)); 
+0

語義,'的sizeof(TCHAR)'而應是'的sizeof(CS :: XCHAR)'。這是所有'CStringT'派生的字符串類型的預定義字符類型。我也建議不要明確鑄造。隱式調用轉換運算符。如果你想明確,你可以把它叫做'GetString()'成員。這樣做可以防止無意中調用轉換操作符。 – IInspectable

+0

@IInspectable我不認爲你可以鍵入'的sizeof(CS :: XCHAR)'並將它編譯。我想你可能是指'sizeof(CString :: XCHAR)',但這與'sizeof(TCHAR)'完全一樣。另外請注意,'LPCTSTR'實際上是一個運算符:https://msdn.microsoft.com/en-us/library/aa300569(v=vs.60).aspx –

+0

*「我想你可能是指'sizeof(CString :: XCHAR)',但這與'sizeof(TCHAR)''完全一樣。「* - 這是真的,它們指定了相同的類型。然而,有一個語義上的區別:雖然'TCHAR'只是一個不相關的類型,'XCHAR'是整個CString實現中使用的類型。*「另外,請注意'LPCTSTR'實際上是一個運算符」* - 這就是爲什麼我之前將它稱爲*「轉換運算符」*的原因。它仍然被隱式調用。正確鏈接到文檔是[here](https://msdn.microsoft.com/en-us/library/sddk80xf.aspx#csimplestringt__operator_pcxstr)。 – IInspectable

0

這是因爲您正在編譯UNICODE定義,而CString是一個寬字符的字符串,其中每個字符佔用兩個字節。寫入文件的內容是您所看到的字符字節,後跟一個零字節。

+3

值得編輯,明確規定'GetLength'將返回什麼'Write'需要的字符數,而不是字節數,因而一半。 – user4581301

0

我一直在開發MFC,Visual C++ 6.0到Visual C++ 2005大約4年,現在專業地支持我們公司的應用程序。

在我的經驗和我所知道的CString類對象中,它們始終以NULL終止。這可能會導致與使用字符數組不同的行爲,但不是上述問題。

我相信你的問題與你作爲參數傳入的緩衝區有關。 LPWSTR是一個32位指針,指向每個此MSDN Reference的16位字符的字符串。

從我可以告訴根據你張貼什麼,你輸出16位Unicode字符和查看他們作爲ANSI因此,這種行爲是可以預料的。如果您打開記事本文件爲Unicode,則不會看到空格。

或者,如果您在寫入文件之前使用ANSI字符集或轉換爲ANSI來構建項目,則當您在記事本中打開輸出時,空格應該消失。

0

試試這個

TCHAR c[] = "Hello!"; 
int charCount = sizeof(c)/sizeof(c[0]); 
myFile.Write(c, charCount*sizeof(c[0])); 

寫會寫只有指定的字節數。 charCount將與ASCII的字節數相同,但是將爲UNICODE的一半。

嘗試上面的代碼更改爲你的類型的文本

https://msdn.microsoft.com/en-us/library/6337eske.aspx

相關問題