为什么我在 C++ 中得到 "forbids converting a string constant to ‘char*’"?

Why do I get "forbids converting a string constant to ‘char*’" in C++?

我正在尝试手动反转大小写,我试过这个:

char* invertirCase(char* str){
    int size = 0;
    char* iterador = str;
    char* retorno = str;

    while (*iterador != '[=11=]') {

        if (retorno[size] < 96) {
            retorno[size] = *iterador + 32;
        }
        else {
            retorno[size] = *iterador - 32;
        }
        iterador++;
        size++;
    }

    return retorno;
}

我想找出错误在哪里,但我不明白,因为我是 C++ 语言的新手。

Why do I get "forbids converting a string constant to ‘char*’" in C++?

该错误消息表示您正在尝试将字符串文字传递给函数。

C++ 中的字符串文字具有按值传递给函数的常量字符数组类型,隐式转换为 const char * 类型。任何更改字符串文字的尝试都会导致未定义的行为。

您可以向函数传递一个由字符串文字初始化的字符数组,例如

char s[] = "Hello";
std::cout << invertirCase( s ) << '\n';

反过来函数可以这样定义

#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;
}

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;
}

您显示的代码中没有“字符串常量”,因此它必须位于调用站点,即如果您正在执行类似 invertirCase("string") 的操作,则 2原因:

  1. 自 C++11 起,C++ 不允许将 字符串文字 分配给 char* 指针。这是因为字符串文字是一个 const char[] 数组,您不能让 pointer-to-non-const 指向 const 数据。所以你需要使用 const char* 来代替。

  2. 然而,这仍然不起作用,因为invertirCase()修改了其str参数指向的数据。您不能修改字符串文字的数据。

因此,您必须将字符串文字复制 到可写内存中。您可以在呼叫站点制作该副本,例如:

char str[] = "string";
invertirCase(str);

或者,您可以在 invertirCase() 中创建副本(但是调用者在使用完后必须释放副本),例如:

char* invertirCase(const char* str){
    int size = 0;
    char* retorno = new char[strlen(str)+1];

    while (*str != '[=11=]') {
        retorno[size] = (*str < 96) ? (*str + 32) : (*str - 32);
        str++;
        size++;
    }

    retorno[size] = '[=11=]';

    return retorno;
}
char *str = invertirCase("string");
...
delete[] str;

否则,根本不要使用 char*。使用 std::string 代替,例如:

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");
...