error: cannot convert 'LPCWSTR' {aka 'const wchar_t*'} to 'LPCSTR' {aka 'const char*'}

closed account (GTXEhUp4)
hello i am trying to do an file finder but i took this error i am new in c++ how could i fix this problem thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<Windows.h>
using namespace std;
int main(){

    //Local variable
    WIN32_FIND_DATA FindFileData;
    HANDLE hFindFile;
    LPCWSTR file = L"C:\\Users\\BATUHAN\\Desktop\\*";
    //STEP-1 FindFirst File Function

    hFindFile = FindFirstFile(
        file, 
        &FindFileData);
    if(INVALID_HANDLE_VALUE == hFindFile){
        cout << "Error in Finding File" <<endl;
        cout << "Error - " << GetLastError() << endl;
    }
    else{
        cout << "File Found" << endl;
        wcout << "File Name : " <<FindFileData.cFileName << endl;
        wcout << "File Size : " <<FindFileData.nFileSizeLow << endl;
    }

    //STEP-2 FindNextFile Function
    while(FindNextFile(hFindFile, &FindFileData)){
        wcout << "File Name : " <<FindFileData.cFileName << endl;
    }
    //STEP-3 File Close Function
    FindClose(hFindFile);

    system("PAUSE");
}
The trouble is on Line 9: LPCWSTR replace with LPCSTR if you are OK with ASCII text.

That or use the wide versions of the other functions, for example see -> https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilew see the W at the end of the function?
Last edited on
Using the standard filesystem library:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <filesystem>
#include <string>
#include <vector>

std::vector<std::string> files_in_directory( const std::string& path_to_dir ) {

    std::vector<std::string> file_names ;

    for( const auto& entry : std::filesystem::directory_iterator(path_to_dir) )
        file_names.push_back( entry.path().string() ) ;

    return file_names ;
}

int main(){

    const std::string path_to_dir = "/dev" ;
    for( const std::string& file_name : files_in_directory(path_to_dir) ) std::cout << file_name << '\n' ;
}

http://coliru.stacked-crooked.com/a/f4ce0bab3171da90
On the Windows platform, it is much recommended to use "Unicode" (wchar_t*) strings for file names and the like, because "ANSI" strings (char*) will not be able to represent any Unicode character that don't exist in your local "ANSI" codepage! But, file names may very well contain such characters, because NTFS is fully Unicode aware! Note that, what Windows calls an "Unicode" string actually is an UTF-16 string, and what Windows calls an "ANSI" string is in fact a multi-byte string encoded in the the local codepage (e.g. Windows-1252). Also note that LP[C]WSTR is an alias for [const] wchar_t*, and LP[C]STR is an alias for [const] char*.

But, if you use "Unicode" strings, then you have to call the matching functions, such as FindFirstFileW and FindNextFileW. Functions FindFirstFileA or FindNextFileA are for "ANSI" strings. The macro FindFirstFile expands to either FindFirstFileA or FindFirstFileW, depending on whether UNICODE is defined!

So, my recommendation is to not change line #9, but instead call the proper function with ...W suffix in lines #12 and #26. You also will have to use the LPWIN32_FIND_DATAW type in line #7.
Last edited on
> On the Windows platform, it is much recommended to use "Unicode" (wchar_t*) strings for file names

On Windows, std::filesystem::path::value_type is wchar_t (and std::filesystem::path::string() yields a std::string with the native path formatted as UTF-8).
That is fine, if you all you are going to do is using functions that understand/expect UTF-8.

However, if you are going to do anything with the Win32 API, then UTF-8 is unsuitable. That is because the "ANSI" functions in the Win32 API take char* strings, but they interpret them using whatever ANSI code-page happens to be configured on the local system – something that is not under your control, and not usually UTF-8 – whereas the "Unicode" functions in the Win32 API only understand UTF-16 (wchar_t*).

You could always use MultiByteToWideChar() to convert the strings from UTF-8 to UTF-16, of course.
Last edited on
ANSI string encoding in WinAPI apps is as dead as Win9x/Me. Every Windows version since uses "Unicode". 16-bit functions and parameters are no longer used by default even though for legacy purposes they are still available.

If'n you use Visual Studio as your compiler/IDE "Unicode" is the default.

WinAPI is not C++, the two are entirely different critters. C++ entry point is int main, WinAPI is int WINAPI WinMain.

If'n you are going to mix WinAPI functionality in a C++ console mode program you should use the 16-bit versions of the data types and functions. Unless you expressly use std::wstring/wchar_t as your C++ data types.

If there is a C++ library available it is better to use the C++ functionality over WinAPI. Using WinAPI restricts your app from being cross-platform. C++17 has the <filesystem> library.

A well-written C++ app can compile without changes on *nixOS or MacOS the same as WinOS.
std::filesystem::path::wstring() would give a UTF-16 encoded string (windows).
That is because the "ANSI" functions in the Win32 API take char* strings, but they interpret them using whatever ANSI code-page
Microsoft has begun to support UTF-8 for its APIs but I don't know how smooth this support is, and it still uses UTF-16 internally, afaik.
Last edited on
std::filesystem::path::wstring() would give a UTF-16 encoded string (windows).

Visual Studio (2022, latest revision update) has some problems with UTF C++ string encodings. The example here (https://en.cppreference.com/w/cpp/filesystem/path/path) crashes when dealing with UTF-32/UTF-8 strings, though it compiles without a problem.
In Microsoft speak, Unicode uses wchar_t type (16 bits). These are referred to as 'wide' char sets - hence 'W'. The other option is Multi-byte character set based upon char type - which is basically ANSI for single char - hence 'A' where used. Unicode is used internally for most (all?) of it's API's. Usually where an ANSI API version is offered, this is internally translated to the Unicode version for in/out params.

'T' is either of these at compile time depending upon where UNICODE is defined or not.
@seeplus, I tried using "Unicode" (the default) and "Multi--byte" encoding with that cppreference example in VS, the app still horked up and crashed no matter what.

If there is a setting(s) solution that would work with VS I haven't found it, but then this is MS we're talking about. Their C/C++ standard compliance comes at a cost some times.
Topic archived. No new replies allowed.