2015-05-26 146 views
0

有很多次這個問題已經被問及許多答案 - 其中沒有一個適用於我,似乎也適用於其他許多問題。問題是關於MFC下的CStrings和8bit字符。我們都希望能夠在所有情況下都能正常工作的答案,而不是特定的情況。將寬CString轉換爲char *

void Dosomething(CString csFileName) 
{ 
    char cLocFileNamestr[1024]; 
    char cIntFileNamestr[1024]; 
    // Convert from whatever version of CString is supplied 
    // to an 8 bit char string 
    cIntFileNamestr = ConvertCStochar(csFileName); 

    sprintf_s(cLocFileNamestr, "%s_%s", cIntFileNamestr, "pling.txt"); 
    m_KFile = fopen(LocFileNamestr, "wt"); 
} 

這是對現有代碼(由其他人)進行調試的補充。 我不想更改函數簽名,它在很多地方使用。 我無法更改sprintf_s的簽名,它是一個庫函數。

+2

在什麼編碼中,你會喜歡你的C風格的字符串,以及你想要對那些不可表示的字符做什麼? – Wintermute

+0

MFC或Windows中沒有8位字符。這些是[MBCS](https://msdn.microsoft.com/en-us/library/cwe8bzh0.aspx)字符,它們是根據特定的[代碼頁](http://en.wikipedia.org/)解釋的。維基/ Code_page)。字符 - 一般來說 - 不能被正確解釋,除非你指定了它的編碼。您的目標字符串應該使用哪種編碼?那些不可代表的角色呢?爲什麼不直接調用[swprintf_s](https://msdn.microsoft.com/en-us/library/ce3zzk1k.aspx)呢? – IInspectable

+0

[Convert CString to const char \ *]可能的重複(http://stackoverflow.com/questions/859304/convert-cstring-to-const-char) – IInspectable

回答

0

的答案,將在所有情況下,沒有一個具體的實例工作...

有沒有這樣的事情。

很容易"ABCD..."wchar_t*轉換爲char*,但它不工作與非拉丁語系語言的方式。

當你的項目是unicode時,堅持到CStringwchar_t

如果您需要上傳數據到網頁或其他東西,然後使用CW2ACA2W進行utf-8和utf-16轉換。

CStringW unicode = L"Россия"; 
MessageBoxW(0,unicode,L"Russian",0);//should be okay 

CStringA utf8 = CW2A(unicode, CP_UTF8); 
::MessageBoxA(0,utf8,"format error",0);//WinApi doesn't get UTF-8 

char buf[1024]; 
strcpy(buf, utf8); 
::MessageBoxA(0,buf,"format error",0);//same problem 

//send this buf to webpage or other utf-8 systems 
//this should be compatible with notepad etc. 
//text will appear correctly 
ofstream f(L"c:\\stuff\\okay.txt"); 
f.write(buf, strlen(buf)); 

//convert utf8 back to utf16 
unicode = CA2W(buf, CP_UTF8); 
::MessageBoxW(0,unicode,L"okay",0); 
+0

再次改變功能而不是轉換字符。 – Peemer

+0

如果保證是英文的,那麼只需使用'CStringA'和'CStringW'在ANSI和Unicode之間來回轉換即可。請參閱Joe Willcoxson的回答。 'CString'被定義爲'CStringW'或'CStringA',具體取決於'#ifdef _UNICODE' –

1

您正在遺漏很多細節,或忽略它們。如果您正在使用定義UNICODE建築(這好像你),然後轉換爲MBCS最簡單的方法是這樣的:

CStringA strAIntFileNameStr = csFileName.GetString(); // uses default code page 

CStringA是CString的的8位/ MBCS版本。

但是,如果您正在翻譯的Unicode字符串包含不在默認代碼頁中的字符,它將填充一些垃圾字符。

而不是使用fopen(),您可以使用_wfopen()這將打開一個Unicode文件的文件。要創建您的文件名,您可以使用swprintf_s()

+0

因此,關於CStrings的一件事情是,它很容易轉換爲傳統的char *字符串。如果我們試圖將這些字符戳到的函數是一個只接受ASCII字符串的遺留函數呢? – Peemer