char* __fastcall GetFileVer(char* sFileName) {
...
return(result);
}
char* szFileVersion = GetFileVer( (char*)Application->ExeName.c_str() );
AboutVersionLbl->Caption = AboutVersionLbl->Caption + (wchar_t)szFileVersion;
Преобразование char* -> wchar_t -> char*
IDE: C++ Builder :: Embarcadero RAD Studio XE (build 3953, +update1)
Пример кода, при выполнении которого вместо номера версии файла (типа 1.2.34.567) выдается не читаемый текст. Функции, которая определяет версию файла, должно передаваться имя файла в char*, и результат возвращает она тоже в char*. Но в форму нужно уже подставлять значение в wchar_t.
Код:
Использование макросов типа _TEXT('...') не решает проблему.
(в программе используется только английский язык)
Спасибо.
Цитата: foxby
Может кто подскажет, как правильно преобразовывать wchar_t в char* и наоборот char* в wchar_t ?
Хочется найти более лаконичное решение, и именно используя код C++ Builder, а не Microsoft C++.
char* -> wchar_t*:
Код:
swprintf(wstr, L"%S", str);
wchar_t* -> char*:
Код:
sprintf(str, "%S", wstr);
Код:
char* __fastcall GetFileVer(char* sFileName) {
...
return(result);
}
char* szFileVersion;
wchar_t* szFileVersionW;
sprintf(szFileVersion, "%S", Application->ExeName.c_str());
szFileVersion = GetFileVer( szFileVersion ) ;
ShowMessage( szFileVersion );
swprintf(szFileVersionW, L"%S", szFileVersion);
AboutVersionLbl->Caption = AboutVersionLbl->Caption + szFileVersionW;
...
return(result);
}
char* szFileVersion;
wchar_t* szFileVersionW;
sprintf(szFileVersion, "%S", Application->ExeName.c_str());
szFileVersion = GetFileVer( szFileVersion ) ;
ShowMessage( szFileVersion );
swprintf(szFileVersionW, L"%S", szFileVersion);
AboutVersionLbl->Caption = AboutVersionLbl->Caption + szFileVersionW;
ShowMessage( szFileVersion ); - теперь выводит читабельную строку с версией файла.
Но как правильно обратно преобразовать в wchar_t? При всевозможных манипуляциях со строкой,
Код:
AboutVersionLbl->Caption = AboutVersionLbl->Caption + (wchar_t)szFileVersion;
включая использование перед ней преобразование с функцией swprintf(...), происходит исключение типа "access violation..."
Может это потому, что вроде swprintf и sprintf не добавляет закрывающий "0" в буфер переменной-строки?
Код:
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", szFileVersion);
AboutVersionLv1->Caption = wcscat(AboutVersionLv1->Caption, szBuffer);
swprintf(szBuffer, L"%S", szFileVersion);
AboutVersionLv1->Caption = wcscat(AboutVersionLv1->Caption, szBuffer);
Почитайте про строки и указатели в Си. Я начну хотя бы с того, что wchar_t - это не указатель на строку, как вы пишете, указателем будет wchar_t *.
к сожалению предложенный вами вариант тоже не подходит, т.к. в этом случает выдается ошибка:
Код:
E2034 Cannot convert 'UnicodeString' to 'wchar_t *
Ошибка указывает на строку
Код:
AboutVersionLbl->Caption = wcscat(AboutVersionLbl->Caption, szBuffer);
Код:
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", szFileVersion);
AboutVersionLbl->Caption += UnicodeString(szBuffer);
swprintf(szBuffer, L"%S", szFileVersion);
AboutVersionLbl->Caption += UnicodeString(szBuffer);
Вот что вам нужно.
если вот такой код запустить на выполнение, то заголовок попросту будет заменен на "12345", т.е. он не "склеивается", а попросту заменяется.
Код:
char* szFileVersion;
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", "12345");
AboutVersionLbl->Caption += UnicodeString(szBuffer);
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", "12345");
AboutVersionLbl->Caption += UnicodeString(szBuffer);
Вот при таком коде уже работает как надо
Код:
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", " 12345");
AboutVersionLbl->Caption = AboutVersionLbl->Caption + UnicodeString(szBuffer);
swprintf(szBuffer, L"%S", " 12345");
AboutVersionLbl->Caption = AboutVersionLbl->Caption + UnicodeString(szBuffer);
Спасибо за советы и потраченное на меня время.
В целом я разочарован в Embarcadero XE. Не ожидал, что вроде бы простые манипуляции со строками будут так напрягать, да и усложнять сам исходный код. Хотя может все же есть нормальные методы, но видимо они спрятаны где-то глубоко в документации :)
Цитата: foxby
Alexander92,
если вот такой код запустить на выполнение, то заголовок попросту будет заменен на "12345", т.е. он не "склеивается", а попросту заменяется.
если вот такой код запустить на выполнение, то заголовок попросту будет заменен на "12345", т.е. он не "склеивается", а попросту заменяется.
Код:
char* szFileVersion;
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", "12345");
AboutVersionLbl->Caption += UnicodeString(szBuffer);
wchar_t szBuffer[10] = {'\0'};
swprintf(szBuffer, L"%S", "12345");
AboutVersionLbl->Caption += UnicodeString(szBuffer);
Возможно, но в любом случае, это уже особенности реализации operator+=() в конкретном классе UnicodeString.
Код:
char* szFileVersion = GetFileVer(const_cast<char*>(Application->ExeName.c_str()) );
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString(szFileVersion);
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString(szFileVersion);
Операторы += для VCL классов не работают, поскольку VCL реализован на дельфи, а там такого нет. В связи с этим во многих местах нумерация массивов начинается с 1, а не с 0. В случае со строками это именно так. Читайте справку и будьте внимательны.
это было бы здорово, но вот заморочка все же остается:
Код:
E2031 Cannot cast from 'wchar_t *' to 'char *'
Может еще как-нить можно или нужно преобразовать тип для Application->ExeName.c_str() ?
Загляните уже в
В результате упорных скитаний по справкам нашел решение проблемы, используя функцию [COLOR="blue"]wcstombs[/COLOR]
Код:
char* __fastcall GetFileVer(char* sFileName) {
...
// здесь код извлечения номера версии из исполняемого файла
return(result);
}
char* szFileVersion; // для номера версии файла
char* pbuf = (char*) malloc( Application->ExeName.Length() ); // выделяем память для буфера
wcstombs( pbuf, Application->ExeName.c_str(), Application->ExeName.Length() ); // преобразуем wchar_t* в char* строку
szFileVersion = GetFileVer( pbuf ); // получаем номер версии в строку типа char*
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString( szFileVersion ); // склеиваем заголовок метки с номером версии файла
...
// здесь код извлечения номера версии из исполняемого файла
return(result);
}
char* szFileVersion; // для номера версии файла
char* pbuf = (char*) malloc( Application->ExeName.Length() ); // выделяем память для буфера
wcstombs( pbuf, Application->ExeName.c_str(), Application->ExeName.Length() ); // преобразуем wchar_t* в char* строку
szFileVersion = GetFileVer( pbuf ); // получаем номер версии в строку типа char*
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString( szFileVersion ); // склеиваем заголовок метки с номером версии файла
Однако новая проблема появилась:
- если запускать программу из под IDE нажатием F9 (Run), то номер версии отображается нормально;
- если же запускать скомпилированный файл (или через Shift+Ctrl+F9), то номер версии нечитабельный, причем при каждом запуске программы отображается разный набор символов;
С чем это может быть связано?
Код:
char *szFileVersion = GetFileVer(AnsiString(Application->ExeName).c_str());
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString(szFileVersion);
AboutVersionLbl->Caption = AboutVersionLbl->Caption + WideString(szFileVersion);
Коротко и наглядно. Я просто как-то не задумывался об AnsiString-преобразовании, т.к. сами Embarcadero-вцы писали, что надо в C++ избавляться от AnsiString.
Я заодно нашел причину вот этой проблемы
Цитата:
- если запускать программу из под IDE нажатием F9 (Run), то номер версии отображается нормально;
- если же запускать скомпилированный файл (или через Shift+Ctrl+F9), то номер версии нечитабельный, причем при каждом запуске программы отображается разный набор символов;
- если же запускать скомпилированный файл (или через Shift+Ctrl+F9), то номер версии нечитабельный, причем при каждом запуске программы отображается разный набор символов;
Оказался виновным Code Guard, и когда я его в свойствах проекта отключил, то теперь и под IDE, и при запуске скомпилированного файла отображаются нормальные читабельные символы.