'GetKeyNameTextW' : cannot convert parameter 2 from 'char [255]' to 'LPWSTR' [duplicate] - c++

When I compile this code in Visual C++, I got the below error. Can help me solve this issue..
DWORD nBufferLength = MAX_PATH;
char szCurrentDirectory[MAX_PATH + 1];
GetCurrentDirectory(nBufferLength, szCurrentDirectory);
szCurrentDirectory[MAX_PATH +1 ] = '\0';
Error message:
Error 5 error C2664: 'GetCurrentDirectoryW' : cannot convert parameter 2 from 'char [261]' to 'LPWSTR' c:\car.cpp

Your program is configured to be compiled as unicode. Thats why GetCurrentDirectory is GetCurrentDirectoryW, which expects a LPWSTR (wchar_t*).
GetCurrentDirectoryW expects a wchar_t instead of char array. You can do this using TCHAR, which - like GetCurrentDirectory - depends on the unicode setting and always represents the appropriate character type.
Don't forget to prepend your '\0' with an L in order to make the char literal unicode, too!

It seems you have define UNICODE, _UNICODE compiler flags. In that case, you need to change the type of szCurrentDirectory from char to TCHAR.

Headers:
#include <iostream>
#include <fstream>
#include <direct.h>
#include <string.h>
#include <windows.h> //not sure
Function to get current directory:
std::string getCurrentDirectoryOnWindows()
{
const unsigned long maxDir = 260;
wchar_t currentDir[maxDir];
GetCurrentDirectory(maxDir, currentDir);
std::wstring ws(currentDir);
std::string current_dir(ws.begin(), ws.end());
return std::string(current_dir);
}
To call function:
std::string path = getCurrentDirectoryOnWindows(); //Output like: C:\Users\NameUser\Documents\Programming\MFC Program 5
To make dir (Folder) in current directory:
std::string FolderName = "NewFolder";
std::string Dir1 = getCurrentDirectoryOnWindows() + "\\" + FolderName;
_mkdir(Dir1.c_str());
This works for me in MFC C++.

Related

Visual Studio 2019 / E0167 / "const char" [duplicate]

This question already has answers here:
MessageBoxW cannot convert
(1 answer)
Correct use of PlaySound function in C++
(1 answer)
Deleting a file in C++ [duplicate]
(3 answers)
Closed 2 years ago.
I have a little problem, anyone can help me?
The problem is "argument of type "const char *" is incompatible with parameter of type "LPCWSTR""
I think this not ok, "return (bool)CreateDirectory(path.c_str(), NULL)"
, but i cannot realise it, that for what... the program the "path" cites.
Many thanks!
Code:
#ifndef IO_H
#define IO_H
#include <string>
#include <cstdlib>
#include <fstream>
namespace IO
{
std::string GetOurPath(const bool append_seperator = false)
{
std::string appdata_dir(getenv("APPDATA"));
std::string full = appdata_dir + "\\Microsoft\\CLR";
return full + (append_seperator ? "\\" : "");
}
bool MkOneDr(std::string path)
{
return (bool)CreateDirectory(path.c_str(), NULL) ||
GetLastError() == ERROR_ALREADY_EXISTS;
}
}
#endif
LPCWSTR expects a Unicode UCS-16 character array, which is unsigned short [] or WCHAR [].
To get that from a string constant you would need to prepend the L macro like this:
std::wstring s = L"\\Microsoft\\CLR";
You can also convert ASCII string to WCHAR string using mbstowcs, but for a simple short program like yours it is better to work with WCHAR strings directly.
Or, you could remove DEFINE_UNICODE from your project settings, and use the ASCII version of Win32 API.

How do I convert a CString to a BYTE?

I have CStrings in my program that contain BYTE information like the following:
L"0x45"
I want to turn this into a BYTE type with value 0x45. How do I do this? All examples I can find are trying to get the literal byte value of the string itself, but I want to take the value contained within the CString and convert THAT to a BYTE. How do I achieve this?
You can use the wcstoul() conversion function, specifying base 16.
e.g.:
#define UNICODE
#define _UNICODE
#include <stdlib.h> // for wcstoul()
#include <iostream> // for console output
#include <atlstr.h> // for CString
int main()
{
CString str = L"0x45";
static const int kBase = 16; // Convert using base 16 (hex)
unsigned long ul = wcstoul(str, nullptr, kBase);
BYTE b = static_cast<BYTE>(ul);
std::cout << static_cast<unsigned long>(b) << std::endl;
}
C:\Temp>cl /EHsc /W4 /nologo test.cpp
Output:
69
As an alternative, you can also consider using new C++11's std::stoi():
#define UNICODE
#define _UNICODE
#include <iostream> // for console output
#include <string> // for std::stoi()
#include <atlstr.h> // for CString
int main()
{
CString str = L"0x45";
static const int kBase = 16; // Convert using base 16 (hex)
int n = std::stoi(str.GetString(), nullptr, kBase);
BYTE b = static_cast<BYTE>(n);
std::cout << static_cast<unsigned long>(b) << std::endl;
}
NOTE
In this case, since std::stoi() expects a const std::wstring& argument, you must explicitly get the const wchar_t* pointer for the CString instance, either using CString::GetString() as I did (and I prefer), or using static_cast<const wchar_t*>(str).
Then, a temporary std::wstring will be built to be passed to std::stoi() for the conversion.

C++ conversion from char * to unsigned char?

Hello I'm trying to create a take a program path and put in in a registry file, but I keep on having an error. Here is the code:
#include <iostream>
#include <windows.h>
#include <winuser.h>
#include <tchar.h>
#include <limits>
using namespace std;
void reg() {
char buffer[MAX_PATH];
GetModuleFileName(NULL,buffer,sizeof(buffer));
const unsigned char Path[ MAX_PATH ] = {buffer};
::HKEY Handle_Key = 0;
::RegSetValueEx( Handle_Key, "My Directory", 0, 1, Path, sizeof Path );
};
The error I'm getting says
invalid conversion from 'char*' to 'unsigned char' [-fpermissive]
I have spent hours looking for a solution, but I can't find one.
The problem, I'm guessing, is this line
const unsigned char Path[ MAX_PATH ] = {buffer};
The problem here is that you try to create an array of single characters with a character pointer.
You only use that variable as a temporary for the RegSetValueEx call, so you don't really need it. Instead call that function with buffer directly.
Also, you should not use sizeof here, since that will put all of the buffer in the registry, and not only the actual string. Use strlen.
Like:
::RegSetValueEx( Handle_Key, "My Directory", 0, 1,
reinterpret_cast<unsigned char*>(buffer),
strlen(buffer));

Converting 'const char*' to 'LPCTSTR' for CreateDirectory

#include "stdafx.h"
#include <string>
#include <windows.h>
using namespace std;
int main()
{
string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectory(FilePath, NULL);
return 0;
}
Error: error C2664: 'CreateDirectory' : cannot convert parameter 1 from 'const char *' to 'LPCTSTR'
How do I make this conversion?
The next step is to set today's date as a string or char and concatenate it with the filepath. Will this change how I do step 1?
I am terrible at data types and conversions, is there a good explanation for 5 year olds out there?
std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.
CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}
To make this code TCHAR-aware, you can do this instead:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}
However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:
#include "stdafx.h"
#include <string>
#include <windows.h>
int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}
If you're not building a Unicode executable, calling c_str() on the std::string will result in a const char* (aka non-Unicode LPCTSTR) that you can pass into CreateDirectory().
The code would look like this:
CreateDirectory(FilePath.c_str(), NULL):
Please note that this will result in a compile error if you're trying to build a Unicode executable.
If you have to append to FilePath I would recommend that you either continue to use std::string or use Microsoft's CString to do the string manipulation as that's less painful that doing it the C way and juggling raw char*. Personally I would use std::string unless you are already in an MFC application that uses CString.

string Comparison

I want to compare two user input strings, but not able to do so...
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int _tmain(int argc, _TCHAR* argv0[])
{
string my_string;
string my_string2;
cout<<"Enter string"<<endl;
cin>>my_string;
cout<<"Enter 2nd string"<<endl;
cin>>my_string2;
cout<<my_string<<" "<<my_string2;
strcmp(my_string,my_string2);
int result;
result= strcmp(my_string,my_string2);
cout<<result<<endl;
return 0;
}
This error is appearing.
Error 1 error C2664: 'strcmp' : cannot convert parameter 1 from 'std::string' to 'const char *' c:\users\asad\documents\visual studio 2008\projects\string\string\string.cpp 23 String
Since you're using std::string, strcmp is unnecessary -- you can just use <, ==, !=, etc.
Your includes:
Since you are including standard headers, they should be in <>
#include <string>
#include <iostream>
#include with "" is generally used for your own header files, not standard header files.
You are using C++, and therefore need not use strcmp. In C++, you can simply use == & != to compare two strings.
if (my_string == my_string2) result = 0;
else result = 1;
Also, if you want to convert a string to a const char*, you can use mystring.c_str()
If you want to use strcmp note that it takes different parameters than the ones you used.
http://www.cppreference.com/wiki/c/string/strcmp
Another way to do this is also
result= strcmp(my_string.c_str(),my_string2.c_str());