Visual Studio 2019 / E0167 / "const char" [duplicate] - c++

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.

Related

Enabling UNICODE in gcc windows api string processing [duplicate]

This question already has answers here:
C++ Convert string (or char*) to wstring (or wchar_t*)
(19 answers)
Closed 2 years ago.
I am trying scan thru windows wave devices, using following test snippet in test.cpp;
using namespace std;
#include <string>
#include <vector>
#include <Windows.h>
int main ()
{
int nDeviceCount = waveOutGetNumDevs();
vector<wstring> sDevices;
WAVEOUTCAPS woc;
for (int n = 0; n < nDeviceCount; n++)
if (waveOutGetDevCaps(n, &woc, sizeof(WAVEOUTCAPS)) == S_OK) {
wstring dvc(woc.szPname);
sDevices.push_back(dvc);
}
return 0;
}
Compiled in PowerShell with gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project), I get this error:
PS xxx> g++ .\test.cpp -c
.\test.cpp: In function 'int main()':
.\test.cpp:14:27: error: no matching function for call to 'std::__cxx11::basic_string<wchar_t>::basic_string(CHAR [32])'
wstring dvc(woc.szPname);
I thought wstring constructor includes support for c-style null-terminated strings. Why am I getting this error?
By default, the UNICODE macro is undefined. This makes the pzPname field be CHAR pzPname[MAXPNAMELEN] in the definition. That’s why the error arises, as the std::wstring is trying to initialize with char data rather than wchar_t data.
To resolve this, place a #define UNICODE statement before including the Windows.h file, or use std::string instead.

c++ #include macro names must be identifiers [duplicate]

This question already has answers here:
what is the difference between #include<> and #define"" [closed]
(2 answers)
Closed 6 years ago.
I'm making a C++ header file for learning purposes. It's supposed to give me the length of the number (be it an int, float, double etc.) without counting the comma. Here's my code:
#ifndef NUMLEN_H
#define NUMLEN_H
#define <cstring>
int numlen (char numberLengthSample[]) //numlen - lenghth of the number, numberLengthSample - the number you put in.
{
int numberLengthDummy = strlen (numberLengthSample); //a temporary int used in counting the length
int numlenc = strlen (numberLengthSample); //the true length of the number
while (numberLengthDummy>0)
{
if (numberLengthSample[numberLengthDummy-1]=='.'||numberLengthSample[numberLengthDummy-1]==',')
{
numlenc--;
}
numberLengthDummy--;
}
return numlenc;
}
#endif // NUMLEN_H
But it gives me 3 errors:
1) (line 3) macro names must be identifiers
2) (line 7) 'strlen' was not declared in this scope (obviously)
3) (line 5 (when executed from my test .cpp)) initializing argument 1 of 'int numlen(char*)' [-fpermissive]|
I tried to look for an answer, yet with no prevail. Any help would be appreciated :) .
In C++ you have to #include headers instead of #define them:
#ifndef NUMLEN_H
#define NUMLEN_H
#include <cstring>
It's not related to the question, but you should only declare functions inside header file and implement them inside source file.
The problem is because you are using #define instead of #include, it should be:
#include <cstring>

How to remove files in visual C++ [duplicate]

This question already has answers here:
What is an 'undeclared identifier' error and how do I fix it?
(13 answers)
Closed 8 years ago.
I am trying to write a line of code that will delete a specific file, but I have tried the DeleteFile function, and it is throwing an "Identifier not found" (Visual Studio error code C3861) message.
The code, which is inside of a button click event is:
DeleteFile(path+"filemaker\\start.ini");
What do I need in my form1.h to make this work?
In manner to use DeleteFile you must #include <Windows.h> since it Win API function.
The argument must be a char* pointer, std::string can't be used as argument.
so you can do as follows:
std::string path = "\\path\\to\\dir\\";
std::string filename = path + "filemaker\\start.ini"; (when path does end with "\\")
DWORD res = DeleteFile(filename.c_str());
You can as well #include <stdio.h> (or <cstdio>) and use
int remove(const char* filename),
it is better since it is cross platform (ANSI C).
like this:
std::string path = "\\path\\to\\dir\\";
std::string filename = path + "filemaker\\start.ini"; (when path does end with "\\")
int res = remove(filename.c_str());
EDIT
You need also to add marshaling, like this:
//includes
#include <msclr\marshal.h>
#include <msclr\marshal_cppstd.h>
now the code:
String^ filepath=path+"filemaker\\start.ini";
const char* tmpptr= msclr::interop::marshal_as<const char*>(filepath);
DeleteFile(tmpptr);

c++ string UTF-8 encoding [duplicate]

This question already has answers here:
How do I print UTF-8 from c++ console application on Windows
(8 answers)
Closed 9 years ago.
I'm new in c++, and I tried to write a very simple code, but the result is wrong, and I don't know how to fix it.
The code is:
#include <iostream>
#include <string>
using namespace std;
int main() {
string test_string = "aáeéöôőüűč♥♦♣♠";
cout << test_string << endl;
return 0;
}
But the result is: a├íe├ę├Â├┤┼Ĺ├╝┼▒─ŹÔÖąÔÖŽÔÖúÔÖá
I am on Windows, using Code::Blocks.
Save file as UTF-8 without BOM signature, and try use printf().
//Save As UTF8 without BOM signature
#include <stdio.h>
#include <windows.h>
int main() {
SetConsoleOutputCP(65001);
char test_string[] = "aáeéöôőüűč♥♦♣♠";
printf(test_string);
return 0;
}
And the result is: aáeéöôőüűč♥♦♣♠
Unfortunately working with UTF-8 on Windows is very problematic.
On Linux, you can simply wstring like this:
Does this code work universaly, or is it just my system?
But unfortunately Windows doesn't have an UTF-8 locale, so you are left with Windows API.
http://www.siao2.com/2007/01/03/1392379.aspx

Converting System::String to Const Char * [duplicate]

This question already has answers here:
how to convert System::String to const char*?
(2 answers)
Closed 7 years ago.
I am using Visual C++ 2008's GUI creator to make a user interface. When a button is clicked, the following function is called. The content is supposed to create a file and name the file after the contents of the textbox "Textbox' with '.txt' at the end. However, that leads me to a conversion error. Here is the code:
private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e) {
ofstream myfile (Textbox->Text + ".txt");
myfile.close();
}
Here is the error:
error C2664: 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream(const char *,std::ios_base::openmode,int)' : cannot convert parameter 1 from 'System::String ^' to 'const char *'
How can I do a conversion to allow this to go through?
I would use marshalling:
//using namespace System::Runtime::InteropServices;
const char* str = (const char*)(void*)
Marshal::StringToHGlobalAnsi(Textbox->Text);
// use str here for the ofstream filename
Marshal::FreeHGlobal(str);
But note that you then use just Ansi strings. If you need unicode support you can use the widechar STL class wofstream and PtrToStringChars (#include <vcclr.h>) to convert from System::String. In that case you do not need to free the pinned pointer.
It's simple!
As you're using managed C++, use the include and operate like:
#include <msclr/marshal.h>
...
void someFunction(System::String^ oParameter)
{
msclr::interop::marshal_context oMarshalContext;
const char* pParameter = oMarshalContext.marshal_as<const char*>(oParameter);
// the memory pointed to by pParameter will no longer be valid when oMarshalContext goes out of scope
}
#include <string>
#include <iostream>
#include <atlbase.h>
#include <atlconv.h>
#include <vcclr.h>
using namespace System;
int main(array<System::String ^> ^args)
{
String^ managedStr = gcnew String(L"Hello, Managed string!");
//If you want to convert to wide string
pin_ptr<const wchar_t> wch = PtrToStringChars(managedStr);
std::wstring nativeWstr(wch);
//if you want to convert to std::string without manual resource cleaning
std::string nativeStr(CW2A(nativeWstr.c_str()));
std::cout<<nativeStr<<std::endl;
Console::WriteLine(L"Hello World");
return 0;
}
Thanks jdehaan. I little modified the code to use it with my 'normal' System::String's.
void MarshalNetToStdString(System::String^ s, std::string& os)
{
using System::IntPtr;
using System::Runtime::InteropServices::Marshal;
const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer( );
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
This is the way if you want to convert System:String -> std:string.
You can convert it to a CString and then add the extension to it.
There is a built-in CString constructor which will allow this conversion to happen
Example:
CString(Textbox->Text)
In your specific case:
private: System::Void Button_Click(System::Object^ sender, System::EventArgs^ e)
{
ofstream myfile (CString(Textbox->Text) + ".txt");
myfile.close();
}
There is an really excellent article in MSDN about String conversions here:
http://msdn.microsoft.com/en-us/library/ms235631%28vs.80%29.aspx
There are many samples to convert String from and to different types.