让 char 的 int 值递增的另一种方法是什么?

What's an alternate way of getting the char's int value to increment?

在制作字符串函数的过程中,我尝试在某个地方构建一个类似于 strlwr() 的函数,我将其命名为 lowercase():

#include <stdio.h>
#include <ctype.h>

char *lowercase(char *text);

int main() {
    char *hello = "Hello, world!";
    printf("%s\n", lowercase(hello));
}

char *lowercase(char *text) {
    for (int i = 0; ; i++) {
        if (isalpha(text[i])) {
            (int) text[i] += ('a' - 'A');
            continue;
        } else if (text[i] == '[=10=]') {
            break;
        }
    }
    return text;
}

我了解到大小写字母的间距是32,我用的就是这个。但是后来我得到了这个错误:

lowercase.c:14:13: error: assignment to cast is illegal, lvalue casts are not supported
            (int) text[i] += 32;
            ^~~~~~~~~~~~~ ~~

如果 char 被认为是 A-Z 中的字母,我想增加它的值。事实证明我不能,因为 char 在一个数组中,而我这样做的方式对计算机来说似乎没有意义。

问:我可以使用哪些替代方法来完成此功能?你能进一步解释为什么这个错误是这样的吗?

演员表是不必要的。 chars 是整数类型,可以无声地递增:

text[i] += 32;

正如一些评论者所指出的,您还应该将字符串更改为可修改的字符串。 char *hello = "..." 声明一个 read-only 字符串文字。使用数组语法使其可写。

char hello[] = "Hello, world!";

您还需要将 isalpha() 切换为 isupper(),以便仅修改大写字母。

顺便说一句,如果将 else if 检查移动到 for 循环的测试条件中,您可以摆脱 breakcontinue

for (int i = 0; text[i] != '[=12=]'; i++) {
    if (isupper((unsigned char) text[i])) {
        text[i] += 32;
    }
}

尽管在 C 中,字符串文字具有 non-constant 字符数组类型,但是您不能更改字符串文字。

char *hello = "Hello, world!";

来自 C 标准(6.4.5 字符串文字)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

所以你应该像字符数组一样声明标识符hello

char hello[] = "Hello, world!";

在函数中你不应该使用像 32 这样的幻数。例如,如果编译器使用 EBCDIC 编码,您的函数将产生错误的结果。

并且在循环中而不是类型 int 你必须使用类型 size_t 因为类型为 int 的对象可能无法存储类型的所有值 size_tsizeof 运算符或函数 strlen.

的 return 类型

此声明

(int) text[i] += 32;

没有意义,因为在表达式的左侧由于转换而有一个右值。

功能可以通过以下方式实现

char * lowercase( char *text ) 
{
    for ( char *p = text; *p; ++p ) 
    {
        if ( isalpha( ( unsigned char )*p ) ) 
        {
            *p = tolower( ( unsigned char )*p );
        } 
    }

    return text;
}