19
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <dos.h>
using namespace std;

class Dir
{
public:
    char* cat;
    Dir()
    {
        cout << "(C:/*)\n";
        cat = new char[50];
        cin >> cat;
    }

    void virtual ShowFiles()
    {
    }

};


class Inside : public Dir
{
public:
    void virtual ShowFiles()
    {
        HANDLE hSearch;
        WIN32_FIND_DATA pFileData;

        hSearch = FindFirstFile(cat, &pFileData);
        if (hSearch != INVALID_HANDLE_VALUE)
            do
            {
                //  if ((pFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
                cout << pFileData.cFileName << "\n";
            } while (FindNextFile(hSearch, &pFileData));
            FindClose(hSearch);
    }
};
int main()
{
    Dir *obj1[2];
    obj1[1] = new Inside;
    obj1[1]->ShowFiles();
    return 0;
}

So I have a program, I need to show with dynamic char cat all file in directory, but it is compilable in Borland C++ but in Visual Studio 15 + Resharper it doesn't work. Severity Code Description Project File Line Error (active) argument of type "char *" is incompatible with parameter of type "LPCWSTR"

Anton Malyshev
  • 8,686
  • 2
  • 27
  • 45
Bogdan Tkachenko
  • 378
  • 1
  • 3
  • 11
  • 1
    Not related to your error, but `cin >> cat` is a buffer overflow waiting to happen. Use `cin >> setw(50) >> cat` instead. Or switch to `std::string` and `std::getline()`. – Remy Lebeau Oct 07 '15 at 20:11

5 Answers5

61

To compile your code in Visual C++ you need to use Multi-Byte char WinAPI functions instead of Wide char ones.

Set Project -> Properties -> Advanced (or. General for older versions) -> Character Set option to Use Multi-Byte Character Set

also see the screenshot

Anton Malyshev
  • 8,686
  • 2
  • 27
  • 45
  • 6
    Or, stop using the `TCHAR` based APIs and use the `char` based APIs instead (`FindFirstFileA()` and `WIN32_FIND_DATAA`). Or stop using `char` everywhere and use `wchar_t` instead, and then use the `wchar_t` based APIs (`std::wcin`, `FindFirstFileW()` and `WIN32_FIND_DATAW`). – Remy Lebeau Oct 07 '15 at 20:06
  • Already tried it, when I see problem first of all I search it on stack then I try to solve it by itself and if I can't do it I ask it. – Bogdan Tkachenko Oct 07 '15 at 20:10
  • All alternatives provided by Remy above should work also. Пожалуйста :) – Anton Malyshev Oct 07 '15 at 20:12
  • I’d recommend using utf-8 (multi-byte) everywhere you can. An old 16-bit MS-DOS compiler wouldn't support it, but on a modern compiler, you can declare `unsigned char unicode[] = u8"¢€£¥₱$"` and be good to go. Or `char16_t unicode[] = u"¢€£¥₱$"` to use the wide API. – Davislor Oct 07 '15 at 21:49
  • @Lorehead On Windows, UTF-16 everywhere is more practical, unless you like having to convert between UTF-8 and UTF-16 all the time. – user253751 Oct 07 '15 at 23:00
  • @immibis Well, utf-8 source files are more practical if only because they take up half the space and work in more compilers. If you want to use utf-16 everywhere, you can do it with `char16_t` and `u"This will be in UTF-16 encoding."`, even in a utf-8 source file. On other systems, `wchar_t` might be ucs-32, but `wchar_t` and `L"A wide-char string."` is portable to POSIX. – Davislor Oct 07 '15 at 23:13
  • Still cannot convert `const char16_t *` to `LPCSTR`. – Summer Sun Mar 29 '18 at 08:00
  • @SummerSun `LPCSTR` is a string of 8-byte chars, not 16-byte. And I suppose `const char16_t *` is a string of 16-byte chars. You need either to use `LPCWSTR` instead of `LPCSTR`, or convert your string to `LPCSTR` using `WideCharToMultiByte` function. – Anton Malyshev Mar 29 '18 at 10:52
  • @AntonMalyshev thank you, I switch from `CreateDirectoryA` to `CreateDirectoryW` and issue got fixed. – Summer Sun Mar 29 '18 at 11:37
  • 6
    In Visual Studio 2019 this is now mapped to: Project -> Properties -> Advanced -> Character -> Use Multi-Byte Character Set – Shrout1 Nov 21 '19 at 16:00
  • Does someone knows how can I set "Use Multi-byte" using VSCODE? – PCampello Sep 10 '20 at 21:01
  • @Shrout1 I have tried this, but it show garbage output... Sometimes, I can't even run the application as I see some antivirus library, awshook.dll shown. – Robert Šandor Sep 14 '20 at 15:12
15

I actually found another way to resolve this error since above method did not work for me.

I casted all my constant character strings with (LPCWSTR). The solution looks like this
Earlier

MessageBox(NULL,"Dialog creation failed! Aborting..", "Error", MB_OK);

After casting to LPCWSTR

MessageBox(NULL, (LPCWSTR) "Dialog creation failed! Aborting..", (LPCWSTR) "Error", MB_OK);

So just copying the (LPCWSTR) and pasting wherever this error was generated resolved all my errors.

Stefan
  • 17,448
  • 11
  • 60
  • 79
MSM
  • 410
  • 6
  • 16
  • It might not fit with your question but whosoever searches this error ends up at this post (just like me) so, it might help others – MSM Apr 27 '17 at 03:39
  • I know this would work, but I'd love to have an explanation of why it is necessary. Does it have to do with some change/peculiarity with newer versions of Visual Studio? – Rick Henderson Feb 14 '22 at 19:58
9

Another way to come by this issue, is to use the Lmacro in front of your string.

MessageBox(NULL, L"Dialog creation failed! Aborting..", L"Error", MB_OK);

See: What does the 'L' in front a string mean in C++?

or

L prefix for strings in C++

Stefan
  • 17,448
  • 11
  • 60
  • 79
3

you can use wchar_t

class Dir
{
public:
    wchar_t* cat;
Dir()
{
    wcout << "(C:/*)\n";
    cat = new wchar_t[50];
    wcin >> cat;
}

    void virtual ShowFiles()
    {
    }

};

In Visual Studio 2013 and later, the MFC libraries for multi-byle character encoding (MBCS) will be provided as an add-on to Visual Studio

Li Kui
  • 640
  • 9
  • 21
2

It will work for any settings:

#include <tchar.h>

MessageBox(NULL, _T("Dialog creation failed! Aborting.."), _T("Error"), MB_OK);
8Observer8
  • 868
  • 10
  • 17