Преобразование QString в LPTSTR, отображается только первый символ

Я пытаюсь преобразовать следующие QString :

QString nom, prenom, promo;
...
QString modelName = nom + "_" + prenom + "_" promo;

в LPTSTR.

До сих пор я использовал это:

LPTSTR mm = (LPTSTR) modelName.utf16();

Но возвращаемый LPTSTR содержит только первый символ QString. Я перепробовал множество способов, включая char *, но ничего не помогло.

Что мне нужно сделать, чтобы получить полную строку QString в LPTSTR?


person Remy San    schedule 01.07.2014    source источник
comment
Где код, который доказывает, что вы получаете только 1. символ? А вы уверены, что используете unicode win32 API?   -  person nos    schedule 01.07.2014
comment
mm записывается впоследствии в файле, который я открываю с помощью другого программного обеспечения. В этом я вижу только одну букву. Но когда я напрямую ввожу имя, LPTSTR mm = TEST CODE; это работает просто хорошо.   -  person Remy San    schedule 01.07.2014
comment
Как мы можем быть уверены, что вы не сделали ничего плохого, когда записывали строку в этот файл? Однако, если LPTSTR mm = TEST CODE работает, вы не компилируете с UNICODE #define, и ваша LPTSTR состоит из 8-битных символов, а не 16-битных символов. Возможно, вам нужно вместо этого modelName.toLocal8Bit() или modelName.toUtf8().   -  person nos    schedule 01.07.2014
comment
Я не тот, кто пишет файл. Я вызываю функцию в библиотеке, предоставленной с программным обеспечением, и я не знаю, что в ней происходит после того, как я передаю ей переменную. Но еще раз, если я прямо заполню mm в коде, например mm = TEST, все работает нормально. И нет, я не уверен, что использую unicode Win32 API. Как я мог это проверить?   -  person Remy San    schedule 01.07.2014
comment
Обратите внимание, что modelName.utf16() стал недействительным, поэтому вы не можете хранить этот указатель где-либо.   -  person Dmitry Sazonov    schedule 01.07.2014
comment
Следующий вопрос: что такое LPTSTR в вашей конфигурации сборки? Это LPSTR или LPWSTR?   -  person Dmitry Sazonov    schedule 01.07.2014
comment
Это вопрос на самом деле; прочитайте комментарии в ответе, это связано с этим.   -  person Remy San    schedule 01.07.2014


Ответы (1)


Если LPTSTR mm = "TEST CODE" работает хорошо, то в вашем проекте sizeof(TCHAR)==1. Схема памяти с прямым порядком байтов для строки в кодировке ascii UTF16:

xx 00 xx 00 xx 00 xx 00 ...

Вот почему с однобайтовым TCHAR ваша строка UTF-16 интерпретируется как строка из одного символа. Первый нулевой байт завершает его.

Есть два решения этой проблемы:

  1. Чтобы использовать UTF-16 TCHAR, вам нужно определить UNICODE для всего проекта. Вы можете либо добавить

    DEFINES += UNICODE
    

    в файл проекта qmake или добавьте

    #define UNICODE
    

    в качестве первой строки вашего кода в каждом заголовке и файле .cpp.

  2. Если вы действительно хотите использовать локально закодированные байтовые TCHAR, вам нужно получить их следующим образом:

    QString modelName = ...;
    QByteArray modelNameLocal = modelName.toLocal8Bit();
    LPTSTR mm = (LPTSTR)modelNameLocal.data();
    

    Значение mm останется действительным, пока modelNameLocal находится в области действия. Вы должны быть осторожны, чтобы убедиться, что пока используется mm, базовый массив байтов также должен существовать.

person Kuba hasn't forgotten Monica    schedule 01.07.2014
comment
@Rems, вы должны понимать разницу между указателем и массивом. Потому что есть много потенциальных ошибок. Куба Обер хорошо все описывает. +1 - person Dmitry Sazonov; 01.07.2014
comment
@DmitrySazonov На самом деле я совсем новичок в C; В основном я работал на Java или Web (php) и не очень привык ко всем этим тонкостям. Кстати, спасибо за помощь! - person Remy San; 01.07.2014