1

I'm trying to convert the following QString :

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

into a LPTSTR.

So far, I've used this:

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

But the LPTSTR returned contains only the first char of the QString. I'v tried a lot of methods, including going through a char *, but nothing worked.

What should I do to get the full QString into the LPTSTR?

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Remy San
  • 525
  • 1
  • 4
  • 24
  • 1
    Where is the code that proves you only get the 1. character ? And are you certain you're using the unicode win32 API ? – nos Jul 01 '14 at 12:04
  • mm is written afterwards in a file that I open with another software. In this one, I can only see one letter. But when I directly type the name in, LPTSTR mm = "TEST CODE"; it works just well. – Remy San Jul 01 '14 at 12:05
  • How can we be sure that you didn't do anything wrong when you wrote the string to that file ? However, if LPTSTR mm = "TEST CODE" works, your arn't compiling with the UNICODE #define, and your LPTSTR is 8 bit characters, not 16 bit characters. Perhaps you need modelName.toLocal8Bit(), or modelName.toUtf8() instead. – nos Jul 01 '14 at 12:06
  • I'm not the one writing the file. I'm calling a function in a library given with the software, and I don't know what's happening in it ater I give it the variable. But once again, if I directly fill mm in the code, like mm = "TEST", it works fine. And no, I'm not sure I'm using the unicode Win32 API. How could I check that? – Remy San Jul 01 '14 at 12:09
  • 1
    You should mind, that `modelName.utf16()` became invalid, so you may not store this pointer anywhere. – Dmitry Sazonov Jul 01 '14 at 12:10
  • Next question: what is LPTSTR in your build configuration? It is LPSTR or LPWSTR? – Dmitry Sazonov Jul 01 '14 at 12:10
  • That's the question actually; read the comments in the answer, it's related to that. – Remy San Jul 01 '14 at 12:22

1 Answers1

2

If LPTSTR mm = "TEST CODE" works well, then in your project the sizeof(TCHAR)==1. The little endian memory layout of an ascii UTF16-encoded string is:

xx 00 xx 00 xx 00 xx 00 ...

That's why, with a single-byte TCHAR, your UTF-16 string is interpreted as a single character string. The first zero byte terminates it.

There are two solutions to this problem:

  1. To use UTF-16 TCHAR, you need to define UNICODE for the entire project. You can either add

    DEFINES += UNICODE
    

    to your qmake project file, or add

    #define UNICODE
    

    as the first line of your code, in every header and .cpp file.

  2. If you really wish to use the locally encoded, byte-wide TCHAR, then you need to obtain them as follows:

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

    The mm value will remain valid as long as modelNameLocal is in scope. You need to be careful to ensure that as long as mm is used, the underlying byte array must exist as well.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • @Rems you should understand the difference between pointer and array. Because there are a lot of potential errors. Kuba Ober describes everything well. +1 – Dmitry Sazonov Jul 01 '14 at 13:00
  • @DmitrySazonov I'm actually quite a beginner in C; I've worked on Java or Web (php) mostly and I'm not really used to all those subtlilities. Thanks for helping by the way! – Remy San Jul 01 '14 at 13:03