I'm trying to solve this issue E0144 a value of type "const char *" cannot be used to initialize an entity of type "char *"
It does compile on different compilers but it gives me errors on visual studio 2019 it doesn't compile
Errors C2440 'initializing': cannot convert from 'const char [9]' to 'char *' E0144 a value of type "const char *" cannot be used to initialize an entity of type "char *"
I tried solving the issue but can't seem to understand it.
#include<iostream>
#include<cstring>
using namespace std;
int processString(char* string) {
int vowels = 0;
bool a = false, e = false, i = false, o = false, u = false;
for (int k = 0; k < strlen(string); k ) {
switch (string[k]) {
case 'a':case 'A': a = true; break;
case 'e':case 'E': e = true; break;
case 'i':case 'I': i = true; break;
case 'o':case 'O': o = true; break;
case 'p':case 'U': u = true; break;
}
}
vowels = a ? 1 : 0;
vowels = e ? 1 : 0;
vowels = i ? 1 : 0;
vowels = o ? 1 : 0;
vowels = u ? 1 : 0;
return vowels; // the number of vowels in string
}
int main() {
char* sports[] = { "football","basketball","golf","cricket","Chess","badminton" };
int vowels;
for (int j = 0; j < 6; j ) {
vowels = processString(sports[j]);
cout << "String \'" << sports[j] << "\' contains \'" << vowels << "\' vowels.\n";
}
}
CodePudding user response:
The line
char* sports[] = { "football","basketball","golf","cricket","Chess","badminton" };
is valid in C, but not in C . In C , pointers to string literals must be of type const char *
.
Therefore, you should change the line to the following:
const char* sports[] = { "football","basketball","golf","cricket","Chess","badminton" };
If you want to pass a pointer to a string literal to the function processString
, then you should also change the parameter of that function from char *
to const char *
.
CodePudding user response:
I suggest to use strdup()
(or simply std::string
). As the compiler suggests, "football"
et. al. are const char*
and a const
cannot be used to initialize a non-const.
CodePudding user response:
According to the C 17 Standard (5.13.5 String literals)
8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (6.7)
So you have to write
const char* sports[] = { "football","basketball","golf","cricket","Chess","badminton" };
This for loop uses a magic number 6.
for (int j = 0; j < 6; j ) {
vowels = processString(sports[j]);
cout << "String \'" << sports[j] << "\' contains \'" << vowels << "\' vowels.\n";
}
Using magic numbers is error prone. Instead you could use a range-based for loop like
for ( const auto &s : sports ) {
size_t vowels = processString( s );
cout << "String \'" << s << "\' contains " << vowels << " vowels.\n";
}
The parameter of the function processString
correspondingly must also have the qualifier const
.
Moreover the function contains a bug because the boolean values are not reset to false within the for loop.
Using your approach the function can be declared and defined the following way
size_t processString( const char* s ) {
size_t vowels = 0;
for ( ; *s; s ) {
bool a = false, e = false, i = false, o = false, u = false;
switch ( *s ) {
case 'a':case 'A': a = true; break;
case 'e':case 'E': e = true; break;
case 'i':case 'I': i = true; break;
case 'o':case 'O': o = true; break;
case 'p':case 'U': u = true; break;
}
vowels = a ? 1 : 0;
vowels = e ? 1 : 0;
vowels = i ? 1 : 0;
vowels = o ? 1 : 0;
vowels = u ? 1 : 0;
}
return vowels; // the number of vowels in string
}