3

I encountered a compilation error in Visual Studio 2015, that I am trying to convert char data to LPWSTR. Can I? Or does it work only with string types?

Here is a piece of my code :

    ⋮
FILE *sortie;
char fichier[256];//   <--- HERE s my char table

int main(int argc, char *argv[])
{
    //on masque 
    HWND hwnd = GetForegroundWindow();
    ShowWindow(hwnd, SW_HIDE);

    int i, lettre, result, lastresult, lastletter, compteur;

    GetCurrentDirectory(256, fichier); 
    strcat(fichier, "\\fichierlog.txt");

Before posting my question I was at:

  1. https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k%28C2664%29&rd=true

  2. C++ cannot convert from enum to LPCTSTR

  3. How to Convert char* to LPWSTR in VC++?

I didn't find my case :(

Community
  • 1
  • 1
VAV
  • 33
  • 1
  • 4

3 Answers3

3

Instead of your current code:

FILE *sortie;
char fichier[256];//   <--- HERE s my char table

int main(int argc, char *argv[])
{
    //on masque 
    HWND hwnd = GetForegroundWindow();
    ShowWindow(hwnd, SW_HIDE);

    int i, lettre, result, lastresult, lastletter, compteur;

    GetCurrentDirectory(256, fichier); 
    strcat(fichier, "\\fichierlog.txt");

do e.g.

auto main() -> int
{
    //on masque 
    HWND hwnd = GetForegroundWindow();
    ShowWindow(hwnd, SW_HIDE);

    int i, lettre, result, lastresult, lastletter, compteur;

    std::wstring fichier( MAX_PATH, L'\0' );//   <--- HERE s my char table
    const DWORD len = GetCurrentDirectory( fichier.size(), &fichier[0] );
    if( len == 0 || len >= fichier.size() ) { throw std::runtime_error( "GetCurrentDirectory failed." ); }
    fichier.resize( len );
    fichier += L"/fichierlog.txt";

    std::ifstream sortie( fichier );

This should fix three issues:

  • You're compiling as Unicode (probably a Visual Studio project), but the code is for the Windows ANSI API.

  • You're using a C++ compiler, but the code is low level C.

  • Too small buffer for maximum path length, and possible buffer overrun for the concatenation.

Note that the ifstream constructor that accepts a wide string is a Microsoft extension. It will however be practically required for Windows C++ compilers by the file system addition to the standard library in C++17.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Your answer is better than mine here. I was wondering is it enough to initialize the string with zero as in `fichier(256, 0);` or does it have to be `L'\0'`? – Barmak Shemirani Jun 17 '15 at 02:50
  • it s clarifying my problem ! – VAV Jun 17 '15 at 02:51
  • @BarmakShemirani: `0` and `L'\0'` have the same effect here, it's just a zero value that's implicitly converted to `wchar_t`. The character literal is just for clarity. But I often use e.g. `L'#'` in order to more easily detect off-by-one errors, which could leave one or more `#` characters in the result. I have yet to detect one, running on 20 years or so with this scheme. But I ain't giving up! :) – Cheers and hth. - Alf Jun 17 '15 at 02:54
  • Thanks. `std::wstring` has about 20 different constructors, I wasn't sure if I had the right one. – Barmak Shemirani Jun 17 '15 at 03:33
2

You are compiling with unicode, so you have to use wchar_t to declare the strings. Instead of strcat use the unicode version which is wcscat.

Also change the strings "\fichierlog.txt" become L"\fichierlog.txt"

FILE *sortie;
//char fichier[256];//   <--- HERE s my char table
wchar_t fichier[256];//   <--- HERE s my char table

//on masque 
HWND hwnd = GetForegroundWindow();
ShowWindow(hwnd, SW_HIDE);

int i, lettre, result, lastresult, lastletter, compteur;

GetCurrentDirectory(256, fichier);
//strcat(fichier, "\\fichierlog.txt");
wcscat(fichier, L"\\fichierlog.txt");
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
1

Your Visual Studio project is set to compile using "widechars" as default encoding (aka UNICODE), so all Windows APIs take wchar_t arrays instead of char arrays when handling strings.

Either set your project to use standard charset or specify the ASCII version of GetCurrentDirectory by using GetCurrentDirectoryA instead.

GetCurrentDirectory is actually not a function, but a pre-processor macro that will route you to GetCurrentDirectoryA or GetCurrentDirectoryW depending on what enconding your compiler is set to use.

Havenard
  • 27,022
  • 5
  • 36
  • 62