Я работаю над кросс-платформенным проектом с использованием Qt. В Windows я хочу передать некоторые символы Юникода (например, путь к файлу, содержащий китайские символы) в качестве аргументов при запуске приложения из командной строки. Затем используйте эти аргументы для создания QCoreApplication
.Как преобразовать LPWSTR в char * с кодировкой UTF-8
По некоторым причинам, мне нужно использовать CommandLineToArgvW
, чтобы получить список аргументов, как это:
LPWSTR * argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
Я понимаю, на современной ОС Windows, LPWSTR
фактически wchar_t*
который 16bit и использует UTF-16 кодировке.
Хотя если я хочу инициализировать QCoreApplication
, требуется только char*
, но не wchar_t*
. QCoreApplication
Таким образом, вопрос: как я могу безопасно преобразовать LPWSTR
возвращаемый CommandLineToArgvW()
функции к char*
без потери кодировки UNICODE (то есть китайские иероглифы еще китайские иероглифы, например)?
Я пробовал много разных способов, но безуспешно:
1:
std::string const argvString = boost::locale::conv::utf_to_utf<char>(argvW[0])
2:
int res;
char buf[0x400];
char* pbuf = buf;
boost::shared_ptr<char[]> shared_pbuf;
res = WideCharToMultiByte(CP_UTF8, 0, pcs, -1, buf, sizeof(buf), NULL, NULL);
3: Преобразовать в QString, а затем преобразовать в UTF-8.
ETID: Проблема решена. Широкий характер UTF-16 для преобразования UTF-8 char
действительно отлично работает без проблем со всеми этими тремя подходами. И в Visual Studio, чтобы правильно просмотреть строку UTF-8 в отладке, необходимо добавить спецификатор формата после имени наблюдаемой переменной (см.: https://msdn.microsoft.com/en-us/library/75w45ekt.aspx). Это та часть, которую я пропустил, и заставил меня думать, что мое преобразование строк было неправильным.
Реальная проблема здесь на самом деле при вызове QCoreApplication.arguments()
, возвращаемый QString
строится QString::fromLocal8Bit()
, что приведет к кодирующим вопросам Windows, когда аргументы командной строки содержат символы Юникода. Обходной путь всегда необходим для извлечения аргументов командной строки в Windows, всегда вызывайте Windows API CommandLineToArgvW()
и конвертируйте 16-битный UTF-16 wchar_t * (или LPWSTR) в 8-битный символ UTF-8 * (одним из три способа, упомянутые выше).
Как вы узнали о завершении вашего вызова на "QCoreApplication"? То есть вы говорите, что хотите, чтобы «китайские иероглифы все еще были китайскими иероглифами». Итак, как вы говорите, что их больше нет. Покажите нам код, который, учитывая соответствующую функцию преобразования, вы ожидаете работать. –
В соответствии с документацией Qt автоматически использует 'CommandLineToArgvW' для вас, * если * вы передаете измененные аргументы конструктору' QCoreApplication'. В нем не указано, что именно «модифицировано» означает, но, по-видимому, цель состоит в том, чтобы просто работать для обычного кода, который просто слепо пересылает аргументы «main», но чтит пожелание клиентского кода, если есть какая-либо разница. См. Http://doc.qt.io/qt-5/qcoreapplication.html#arguments –
Возможный дубликат [Windows Unicode командной строки argv] (http://stackoverflow.com/questions/4101864/windows-unicode-commandline-argv) –