2015-05-26 2 views
0

Существует много вопросов, заданных этим вопросом, и столько ответов - ни одна из них не работает для меня и, кажется, многих других. Речь идет о широких CStrings и 8bit-символах под MFC. Мы все хотим получить ответ, который будет работать во всех случаях, а не в конкретном случае.Преобразование широкого 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. Это [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*, но она не работает таким образом с не-латинских языках.

Придерживайтесь CString и wchar_t, когда ваш проект юникод.

Если вам нужно загрузить данные на веб-страницу или что-то еще, используйте CW2A и CA2W для преобразования 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. См. Ответ Джо Вилкокссона. 'CString' определяется как' CStringW' или 'CStringA' в зависимости от' #ifdef _UNICODE' –

1

Вы оставляете много деталей или игнорируете их. Если вы строите с UNICODE определен (который, кажется, вы), то самый простой способ преобразовать в MBCS, как это:

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

CStringA является 8-бит/MBCS версия CString.

Однако он будет заполняться некоторыми символами мусора, если строка юникода, которую вы переводите, содержит символы, которые не находятся на кодовой странице по умолчанию.

Вместо использования fopen() вы можете использовать _wfopen(), который откроет файл с именем файла в формате unicode. Чтобы создать имя файла, вы должны использовать swprintf_s().

+0

Итак, одна из вещей, сказанная о CStrings, заключается в том, что ее легко преобразовать в традиционные строки char *. Что делать, если функция, которую мы пытаемся вытолкнуть эти символы, - это унаследованная функция, которая принимает только символы char * в ascii? – Peemer

Смежные вопросы