Unable to create an array of wchar_t - c++

In my code I have an array of wchar_t:
wchar_t paths [6] = {L"C:\\Program Files\\SomeAppsSuiteFolder1", L"C:\\Program Files\\SomeAppsSuiteFolder2", L"C:\\Program Files (x86)\\SomeAppsSuiteFolder1", L"C:\\Program Files (x86)\\SomeAppsSuiteFolder2", L"C:\\SomeAppsSuiteFolder1", L"C:\\SomeAppsSuiteFolder2"};
Later on I use the array in for loop. The problem is, that for this line I get following errors:
error: too many initializers for 'wchar_t [6]'
error: initializer-string for array of chars is too long [-fpermissive]
What's more, in for loop I have if conditional like this one:
if(GetFileAttributesW(paths[i])!=INVALID_FILE_ATTRIBUTES) {...}
And, again, I get an error here:
error: invalid conversion from 'wchar_t' to 'LPCWSTR {aka const wchar_t*}' [-fpermissive]
Strange enough, similar code used to compile correctly some months ago... What's the problem?

You need
const wchar_t* paths[6] = ....

You need to use:
wchar_t *paths[6] = ...
^
A wchar_t is a single (wide) character, not a string of them.
So, if you want an array of wide strings, you should use the pointer variant.
The declarator wchar_t xyzzy[6] gives you six characters rather than six character arrays.

Related

error: cannot convert 'const CHAR**' {aka 'const char**'} to 'LPCSTR' {aka 'const char*'} in C++

I have a big chunk of code that I am debugging, and I am stuck trying to figure out why I get the following error when I try to build the project:
"error: cannot convert 'const CHAR**' {aka 'const char**'} to 'LPCSTR'
{aka 'const char*'}"
The issue is with the wsKey parameter. SHRegGetValue is a function defined in the Shlwapi.h header, but I don't know how to fix this and I am inexperienced with the Windows API. Please let me know if there is a solution.
LPCSTR wsKey[MAX_PATH] = {"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"};
WCHAR wsValue[MAX_PATH] = L"ProxyEnable";
DWORD dwValue = (DWORD)FALSE;
DWORD dwSize = sizeof(dwValue);
LONG nStatus = SHRegGetValue(HKEY_CURRENT_USER, wsKey, wsValue, SRRF_RT_DWORD, NULL, &dwValue, &dwSize);
The line:
LPCSTR wsKey[MAX_PATH] = {"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"};
declares wsKey to be an array of MAX_PATH character pointers, the first of which points to the given string literal. If this is really what you want, then the second argument to your SHRegGetValue call should be that first element: wsKey[0].
However, what is more likely, is that you need wsKey to be an array of MAX_PATH characters – not pointers. Like this:
const CHAR wsKey[MAX_PATH] = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; // Note the removal of the enclosing {...} braces!
You also have an error with the third parameter to SHRegGetValue: this should be a char (or CHAR) string, not a WCHAR string (you are mixing up the ANSI and Unicode versions of the call). Declare wsValue like this, to use the ANSI version:
CHAR wsValue[MAX_PATH] = "ProxyEnable";
Alternatively, if you intend to use the wide-character (Unicode) version, then you need to change your wsKey to a wide-character string. (This seems more likely, given the variable names.)
const WCHAR wsKey[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
WCHAR wsValue[MAX_PATH] = L"ProxyEnable";
Isn't your question answered in your title: const char** is not const char*. Why you expect that it should work?
I assume it's a copy & paste error. You should write:
LPCSTR wsKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
LPCSTR is an alias to const char *

how to use strcmp in g++

I compiled .cc file whith g++ on linux ubuntu, I want to use srtcmp() function to compare two strings. the strings are not constant. user will give both of them, but I get this error:
error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
and this is my code:
if (!strcmp(a[i].personalNo,pcode)){
#some code
}
which function can I use instead of strcmp() to compare two strings?
The problem isn't on the function but on the way that you're using it.
int strcmp ( const char * str1, const char * str2 );
strcmp takes two const char * arguments.
The error tells you that you are giving the function a char so the problem is on the types of personalNo and/or pcode. Your mistake is probably on the declaration of the type of those two variables. You would want to change their type to char * as char only stores one character while char * is an array of characters.
Also, an another way to compare two strings in C++ is to use std::string. Then you can just do the following (provided that both personalNo and pcode are std::string:
if (a[i].personalNo != pcode){
#some code
}

Setting CHAR16* to a #define string?

I'm a little confused on the proper way to do this. I have a #DEFINE that contains a string, and I have a CHAR16* that I want to set to that string. How would I properly do this? I've tried:
#DEFINE MYSTRING "HELLO"
CHAR16* THISONE;
THISONE = MYSTRING;
Why won't this work? I want to be able to print out the string in THISONE. I get a compiler warning regarding incompatible types. I'm sure I'm missing something small?
You're defining a narrow string literal "HELLO", but trying to use a CHAR16 pointer to point to it. That's not a compatible assignment. As clang says:
example.cpp:9:13: error: assigning to 'wchar_t *' from incompatible type
'const char [6]'
THISONE = MYSTRING;
^ ~~~~~~~~
1 error generated.
(I changed the type from CHAR16 * to wchar_t * since I'm not on windows - the semantics are the same).
To fix it, you need to add an L in front of the string constant:
#define MYSTRING L"HELLO"
And then it will compile. In C, you're done. In C++, however, you will probably still get a warning:
example.cpp:9:15: warning: conversion from string literal to 'wchar_t *' is
deprecated [-Wdeprecated-writable-strings]
THISONE = MYSTRING;
^
example.cpp:3:18: note: expanded from macro 'MYSTRING'
#define MYSTRING L"HELLO"
^
1 warning generated.
Change the definition to:
const wchar_t *THISONE;
To fix that warning. I guess in your case that would be:
const CHAR16 *THISONE;
Editorial note - in the future, please show your real code. #DEFINE (with the capital letters) isn't valid C or C++.
You probably want something like:
// Update: As carl points out, there is more to this for wide chars
const CHAR16* THISONE = MYSTRING;
You can explore more about c-strings here and also from within this very site.
You probably want to assign it as a global variable. In this case you need:
#define MYSTRING "HELLO"
CHAR* THISONE = MYSTRING;
or
#define MYSTRING L"HELLO"
CHAR16* THISONE = MYSTRING;
If assignment is in function (main() or other) you can make assignment not at the same place as variable creation.
Actually, I'm not sure if there is such a type "CHAR16"

C++: Having unicode console title..?

When I try to set my console's title to a string that has unicode characters in it, using SetConsoleTitle(), the title displays just some garbage characters instead.
I have also tried the SetConsoleTitleW() function, but that gives me the following error:
error: cannot convert 'const char*' to 'const WCHAR*' for argument '1' to 'BOOL SetConsoleTitleW(const WCHAR*)'
Any advice?
You have to use wide string literal, that is:
SetConsoleTitleW(L"DиD");
The L, before a quote denotes, that this is a wchar_t* string.
Also, for completness I have to say, that in C++11, there are new string literal prefixes defined:
const char a[] = u8"for a UTF-8 string.";
const char_16_t b[] = u"for a UTF-16 string.";
const char_32_t c[] = U"for a UTF-32 string.";
as usual wikipedia has more detailed note about that.
It looks as if you are attempting to send UTF-8-encoded data to a function that expects UTF-16-encoded data.
You need to either convert the string literal to UTF-16 (i.e. WCHAR*) before passing it to the function, or create the literal as a WCHAR* literal (which I believe is done using the syntax L"DиD").

How to add strings to a 2d array of char elements?

I have the below program written in C++:
#include <iostream>
using namespace std;
int main()
{
int age[5];
char name[5][10];
age[0]=10;
age[1]=20;
age[2]=30;
age[3]=25;
age[4]=40;
name[0]="abc";
name[1]="abc";
name[2]="abc";
name[3]="abc";
name[4]="abc";
cout<<name[0]<<" is "<<age[0]<<"years old";
cout<<"\n";
cout<<name[1]<<" is "<<age[1]<<"years old";
cout<<"\n";
cout<<name[2]<<" is "<<age[2]<<"years old";
cout<<"\n";
cout<<name[3]<<" is "<<age[3]<<"years old";
cout<<"\n";
cout<<name[4]<<" is "<<age[4]<<"years old";
cout<<"\n\n";
system("PAUSE");
}
When I compile and run it, I get these errors:
error C2440: '=' : cannot convert
from 'const char [3]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
I am running MSVC 2008 under Windows 7. I have tried many possible solutions but I failed in fixing this. Any help would be appreciated,
You are treating the name array as if it was defined thus:
char *name[5];
So either define it that way, or use the following code to populate it:
strcpy(name[0], "abc");
strcpy(name[1], "abc");
strcpy(name[2], "abc");
strcpy(name[3], "abc");
strcpy(name[4], "abc");
I prefer the former choice. The point being you are trying to assign a char * to a char [] which is what strcpy is for. Given you are manipulating initialized C strings in this case anyway, you might as well deal with char * throughout the code.
You should use std::string for this purpose. The use of char* and char[] to represent strings is deprecated in C++ for many good reasons.
Given the program snippet, name can be initialized at the declaration itself.
char name[5][10] = { "abc", "abc", "abc", "abc", "abc" } ;
// ^ index 5 is not necessary. char name[][10] = { .. } would also suffice.
Specified the length of each row is 10 but only using first 3 indexes of it. Every 3rd index ( i.e., 4th element in the array ) is automatically added with a '\0'.
Initialization can be done in case of age array too.
You can use also std::string name[10] instead of 2d char's array. In this case only you can assign new values to the strings through operator '='.
Otherwise you should to use array of char* and use strcpy() function for assignment.