0

I am looking for ways to convert a PCHAR* variable to a TCHAR* without having any warnings in Visual Studio( this is a requirement)? Looking online I can't find a function or a method to do so without having warnings. Maybe somebody has come across something similar?

Thank you !

Ioana
  • 53
  • 7
  • 1
    You can convert the *pointers* with a simple cast. But that's probably not want you really want to do. If you want to change the content of the string pointed to, that's more complicated. – Adrian Mole Dec 29 '20 at 16:37
  • The problem is a cast throws off a warning, I need a solution that does not create a warning as I am compiling the project with Warning Level 4 and Treat Warnings as Errors: Yes – Ioana Dec 29 '20 at 16:43
  • @Ioana _"The problem is a cast throws off a warning"_ Sure, because these types point to totally different data structrures behind. Thes aren't equivalent, and such you can't simply cast it. – πάντα ῥεῖ Dec 29 '20 at 16:45
  • Does this answer your question? [Convert char \* to LPWSTR](https://stackoverflow.com/questions/6858524/convert-char-to-lpwstr) – πάντα ῥεῖ Dec 29 '20 at 16:46
  • Without seeing your code it is difficult to suggest a solution. `PCHAR` is `char*`, `TCHAR` is either `wchar_t` or `char`. There might be something wrong in your program if you need to convert a `PCHAR*` to a `TCHAR*`. (see https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types#tchar) – Bodo Dec 29 '20 at 16:54
  • @Ioana It may be as simple as changing a string literal `"text"` to its wide counterpart `L"text"`, or it may require reencoding the strings on the fly. It's hard to guess which one without seeing the actual code. – dxiv Dec 29 '20 at 17:37
  • 1
    I was given a half functioning project in C where I can change only 2 files and I have to make the other half. The PCHAR comes from the function declaration(can t be changed) and TCHAR comes from GetCurrentDirectory. I want to concatenate the 2 using _tcscat_s but I need to convert the PCHAR first. As for the link, it works but the TCHAR* is getting some garbage values from memory allocation when it's initialized. – Ioana Dec 29 '20 at 19:14
  • @Ioana You should [edit](https://stackoverflow.com/posts/65495515/edit) all that context into the question, not as a comment. It helps narrow down the focus, and would also make it less likely for it to be closed as a duplicate of the generic question. – dxiv Dec 30 '20 at 04:16

1 Answers1

0

convert a PCHAR* variable to a TCHAR*

  • PCHAR is a typedef that resolves to char*, so PCHAR* means char**.

  • TCHAR is a macro #define'd to either the "wide" wchar_t or the "narrow" char.

In neither case can you (safely) convert between a char ** and a simple character pointer, so the following assumes the question is actually about converting a PCHAR to a TCHAR*.

PCHAR is the same TCHAR* in ANSI builds, and no conversion would be necessary in that case, so it can be further assumed that the question is about Unicode builds.

The PCHAR comes from the function declaration(can t be changed) and TCHAR comes from GetCurrentDirectory. I want to concatenate the 2 using _tcscat_s but I need to convert the PCHAR first.

The general question of converting between narrow and wide strings has been answered before, see for example Convert char * to LPWSTR or How to convert char* to LPCWSTR?. However, in this particular case, you could weigh the alternatives before choosing the general approaches.

  1. Change your build settings to ANSI, instead of Unicode, then no conversion is necessary.

    That's as easy as making sure neither UNICODE nor _UNICODE macros are defined when compiling, or changing in the IDE the project Configuration Properties / Advanced / Character Set from Use Unicode Character Set to either Not Set or Use Multi-Byte Character Set.

    Disclaimer: it is retrograde nowadays to compile against an 8-bit Windows codepage. I am not advising it, and doing that means many international characters cannot be represented literally. However, a chain is only as strong as its weakest link, and if you are forced to use narrow strings returned by an external function that you cannot change, then that's limiting the usefulness of going full Unicode elsewhere.

  2. Keep the build as Unicode, but change just the concatenation code to use ANSI strings.

    This can be done by explicitly calling the ANSI version GetCurrentDirectoryA of the API, which returns a narrow string. Then you can strcat that directly with the other PCHAR string.

  3. Keep it as is, but combine the narrow and wide strings using [w]printf instead of _tcscat_s.

    char szFile[] = "test.txt";
    PCHAR pszFile = szFile;                           // narrow string from ext function
    
    wchar_t wszDir[_MAX_PATH];
    GetCurrentDirectoryW(_MAX_PATH, wszDir);          // wide string from own code
    
    wchar_t wszPath[_MAX_PATH];
    wsprintf(wszPath, L"%ws\\%hs", wszDir, pszFile);  // combined into wide string
    
    
dxiv
  • 16,984
  • 2
  • 27
  • 49