为什么我收到“禁止将字符串常量转换为“char*””在 C++ 中?

发布于 2025-01-16 09:11:53 字数 452 浏览 5 评论 0原文

我试图手动反转大小写,我尝试了以下操作:

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

我试图找出错误在哪里,但我不明白,因为我对 C++ 语言还很陌生。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜清冷一曲。 2025-01-23 09:11:53

为什么我在 C++ 中收到“禁止将字符串常量转换为 'char*'”?

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

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

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;
}
永不分离 2025-01-23 09:11:53

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

  1. 自 C++11 起,C++ 不允许将字符串文字分配给 char* 指针。这是因为字符串文字是一个 const char[] 数组,并且不能有指向 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 != '\0') {
        retorno[size] = (*str < 96) ? (*str + 32) : (*str - 32);
        str++;
        size++;
    }

    retorno[size] = '\0';

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

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:

  1. 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 a const char[] array, and you can't have a pointer-to-non-const pointing at const data. So you need to use const char* instead.

  2. however, that will still not work, because invertirCase() modifies the data pointed at by its str 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");
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文