字符数组不可赋值。

7

好的,我想将一个单词保存在一个char数组中,但它给了我一个错误。

这是我的代码:

#include <stdio.h>
#include <time.h> 
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char yesno[30] = "n";        //yes/no answer
    char class[30] = "undefined";//choosen class 
    int classchoosen = 0;        

    /* initialize random seed: */
    srand ( time(NULL) );

    printf("Welcome, which class do you wanna play with? \n");
    printf("Type W for Warrior, M for Mage or R for Ranger. Then press Enter\n");
    while(classchoosen == 0)
    {
        scanf("%s", class);
        if(strcmp(class, "W") == 0)
        {
            classchoosen = 1; 
            class = "Warrior";
        }
        if(strcmp(class, "M") == 0)
        {
            classchoosen = 1; 
            class = "Mage";
        }
        if(strcmp(class, "R") == 0)
        {
            classchoosen = 1; 
            class = "Ranger";
        }
        if(classchoosen == 0)
        {
            class = "undefined";
        }
        printf("So you wanna play as a %s? Enter y/n", class);
        classchoosen = 0; //For testing, remove later 

    }
    while(1)
    {
        /* Irrelevant stuff */ 
    }
}

它给了我以下错误:
damagecalc.c:44:13: error: expected identifier
                        class -> "warrior";
                                 ^
damagecalc.c:49:10: error: array type 'char [30]' is not assignable
                        class = "mage";
                        ~~~~~ ^
damagecalc.c:54:10: error: array type 'char [30]' is not assignable
                        class = "ranger";
                        ~~~~~ ^
damagecalc.c:58:10: error: array type 'char [30]' is not assignable
                        class = "warlock";
                        ~~~~~ ^
4 errors generated.

我知道我可以在字符串比较后立即打印出类名,但这件事真的让我很烦恼,我想知道为什么它不起作用。
PS:请原谅我可能犯的任何明显错误,我最近才开始从事PC编程,之前在uC上工作了几年。

为什么不使用 char yesno='n'; 而是使用 char yesno[30] = "n"; - Meninx - メネンックス
4个回答

16

是的,char数组和所有其他数组一样不可赋值。你应该使用strcpy

strcpy(class, "Warrior");

等等,还有其他内容。

另外,您无需声明char class[30];,因为我在您的代码中看到的最长字符串是"undefined",所以

char class[10];

字符串长度为"undefined"的9个字符加上一个空字符'\0',共10个字符,应该是没问题的。

而你可以通过以下方式防止使用scanf函数造成的缓冲区溢出。

scanf("%1s", class);

既然您只想读取1个字符,则比较应该更简单,只需

if (class[0] == 'M')
    strcpy(class, "Mage");

或者甚至这样更易读

classchosen = 1;
switch (class[0])
{
case 'M':
    strcpy(class, "Mage");
    break;
case 'R':
    strcpy(class, "Ranger");
    break;
case 'W':
    strcpy(class, "Warrior");
    break;
default:
    classchosen = 0;
}

最后,请确保scanf实际成功,它会返回匹配的参数数量,所以在你的情况下,检查应该是这样的:

and finally check that scanf actually succeeded, it returns the number of arguments matched so in your case a check would be like

if (scanf("%1s", class) == 1) ...

@Luxuspunch,以下是一些改进您代码的建议。 - Iharob Al Asimi
@Luxuspunch 如果你认为任何答案对你有帮助,你可以通过点击勾选标记来接受答案,请参见这里。也许你已经知道了,但以防万一你不知道... - Iharob Al Asimi
抱歉我在吃东西。无论如何,非常感谢所有在这里贡献的人。当有人能帮助我或者我能帮助别人时,总是能让我的一天变得更美好 :) 我也很欣赏你们的改进。正如我在帖子中所说,这是一个早期版本,但我没有意识到它可以被优化得如此之多。 - Luxuspunch

6

看到这里,不仅适用于字符数组,而且适用于所有类型的数组,但问题是为什么?当我们可以分配其他变量时,为什么不能分配数组?原因是:

int a[size];
a = {2,3,4,5,6};

因为在这里,数组的名称表示数组第一个位置的地址。
printf("%p",a); // let suppose the output is 0x7fff5fbff7f0

我们的意思是

0x7fff5fbff7f0 = something; 这是不正确的。 是的,我们可以执行 a[0] = something,这代表将数组在第0个位置赋值。


1
 class = "Ranger";

应该是

strcpy(class,"Ranger");

在所有地方修复相同的问题。字符数组不可分配。


是的,谢谢你的回答。奇怪的是,我在大约一个小时的研究中从未找到过这个。我真的开始怀疑我的谷歌搜索技巧了。我会尽快将这个问题标记为已解决。 - Luxuspunch
@Luxuspunch 没问题,但这是处理 C 语言字符串的基础。 - Gopi
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Luxuspunch
@Luxuspunch,要在谷歌上搜索这些内容并不容易,但我向您保证,每天都有很多类似的问题在SO上被问到,我已经回答了很多问题,其中问题正是这个。 - Iharob Al Asimi

0

class = "Warrior"; 改为 strcpy(class, "warrior");

class = "Mage"; 改为 strcpy(class, "Mage");

class = "Ranger"; 改为 strcpy(class, "Ranger");

class = "undefined"; 改为 strcpy(class, "undefined");

这样就可以了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接