I'm trying to invert the case manually, and I tried this:
char* invertirCase(char* str){
int size = 0;
char* iterador = str;
char* retorno = str;
while (*iterador != '\0') {
if (retorno[size] < 96) {
retorno[size] = *iterador 32;
}
else {
retorno[size] = *iterador - 32;
}
iterador ;
size ;
}
return retorno;
}
I'm trying to figure out where's the error, but I don't get it since I'm pretty new at C language.
CodePudding user response:
Why do I get "forbids converting a string constant to ‘char*’" in C ?
The error message means that you are trying to pass a string literal to the function.
String literals in C have types of constant character arrays that passed by value to functions are implicitly converted to the type const char *
. And any attempt to change a string literal results in undefined behavior.
You could pass to the function a character array initialized by a string literal as for example
char s[] = "Hello";
std::cout << invertirCase( s ) << '\n';
In turn the function can be defined the following way
#include <cctype>
char * invertirCase( char *str )
{
for ( char *p = str; *p; p )
{
unsigned char c = *p;
if ( std::isalpha( c ) )
{
if ( std::islower( c ) )
{
*p = std::toupper( c );
}
else
{
*p = std::tolower( c );
}
}
}
return str;
}
or
char * invertirCase( char *str )
{
for ( char *p = str; *p; p )
{
unsigned char c = *p;
if ( std::islower( c ) )
{
*p = std::toupper( c );
}
else if ( std::isupper( c ) )
{
*p = std::tolower( c );
}
}
return str;
}
CodePudding user response:
There is no "string constant" in the code you have shown, so it would have to be at the call site, ie if you were doing something like invertirCase("string")
, which will not work, for 2 reasons:
since C 11 onward, C does not allow a string literal to be assigned to a
char*
pointer. This is because a string literal is aconst char[]
array, and you can't have a pointer-to-non-const pointing at const data. So you need to useconst char*
instead.however, that will still not work, because
invertirCase()
modifies the data pointed at by itsstr
parameter. You can't modify the data of a string literal.
So, you will have to make a copy of the string literal into writable memory. You can either make that copy at the call site, eg:
char str[] = "string";
invertirCase(str);
Or, you can make the copy inside of invertirCase()
(but then the caller will have to free the copy when done using it), eg:
char* invertirCase(const char* str){
int size = 0;
char* retorno = new char[strlen(str) 1];
while (*str != '\0') {
retorno[size] = (*str < 96) ? (*str 32) : (*str - 32);
str ;
size ;
}
retorno[size] = '\0';
return retorno;
}
char *str = invertirCase("string");
...
delete[] str;
Otherwise, simply don't use char*
at all. Use std::string
instead, eg:
std::string invertirCase(const std::string &str){
std::string retorno;
retorno.reserve(str.size());
for(char ch : str) {
retorno.push_back((ch < 96) ? (ch 32) : (ch - 32));
}
return retorno;
}
std::string str = invertirCase("string");
...