【问题标题】:Varying string variable in an if condition在 if 条件下改变字符串变量
【发布时间】:2018-02-11 16:57:40
【问题描述】:

我使用这个程序将输入 mm 作为一年中的月份并打印出月份的名称:

#include <stdio.h>
#include <string.h>
int main(){
int mm;
printf("input month ");
scanf("%d", &mm);
char mname[9];
if (mm == 1) {mname = "January";}
if (mm == 2) {mname = "February";}
if (mm == 3) {mname = "March";}
if (mm == 4) {mname = "April";}
if (mm == 5) {mname = "May";}
if (mm == 6) {mname = "June";}
if (mm == 7) {mname = "July";}
if (mm == 8) {mname = "August";}
if (mm == 9) {mname = "September";}
if (mm == 10) {mname = "October";}
if (mm == 11) {mname = "November";}
if (mm == 12) {mname = "December";}
printf("%d is month %s", mm, mname);

return 0;
}

它给数组类型的表达式赋值错误。请帮忙

【问题讨论】:

  • char mname[9]; -> const char *mname;
  • 或者更好:static const char *months[] = { "January", "February", "March", ... }; const char *mname = months[mm - 1]; (需要添加完整性检查)。
  • 即使你可以char mname[9] 太短,无法容纳"September"
  • {mname = XXX;} -> {strcpy(mname, XXX;}mname[9]; -> mname[10];(NUL 终止符需要多一个字符)。

标签: c arrays string variables


【解决方案1】:

Michael Walz 两个伟大的 cmets 并将它们添加为答案:

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

void main(int argc, char** argv)
{
    int mm = 0;

    printf("Please enter a month number [1-12]:\n");
    scanf("%d", &mm);
    static const char* months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

    if (mm >= 1 && mm <= 12)
    {
        printf("%d is month %s", mm, months[mm - 1]);
    }
    else
    {   
        printf("You have entered an invalid month number %d\n", mm);
    }
}

有效性检查已完成(在上面的 cmets 中提到)。

希望对您有所帮助。

干杯,

伙计。

【讨论】:

  • 附注:如果您将某人的评论变成答案而不提及他们的名字,那么没有人会责怪您。
【解决方案2】:

数组类型基本上是常量指针,因此当您尝试为指针 mname 分配新值时,编译器会检测到错误。

您可以使用以下示例中的函数 strcpy 来解决问题:

    if (mm == 1) {
        strcpy(mname, "January");
    }

【讨论】:

    【解决方案3】:

    基本上有两种不同的方式来思考/谈论字符串:

    1. 一个字符数组,以'\0' 字符结尾。 (这是 C 中字符串的正式定义。)

    2. 作为指向字符的指针,或char *,指向字符序列(数组)的第一个字符,以'\0' 字符结尾。

    所以你可以声明一个数组,并将一个字符串复制到其中:

    char arraystring[10];
    strcpy(arraystring, "Hello");
    

    或者你可以声明一个数组,声明的时候给它一个初始值:

    char arraystring2[] = "world!";
    

    或者你可以声明一个指针,让它指向一个字符串:

    char *pointerstring;
    pointerstring = "Goodbye";
    

    或者你可以声明一个指针,并给它一个初始值:

    char *pointerstring2 = "for now";
    

    值得了解这些在记忆中的“样子”:

                    +---+---+---+---+---+---+---+---+---+---+
    arraystring:    | H | e | l | l | o |\0 |\0 |\0 |\0 |\0 |
                    +---+---+---+---+---+---+---+---+---+---+
    
                    +---+---+---+---+---+---+---+
    arraystring2:   | w | o | r | l | d | ! |\0 |
                    +---+---+---+---+---+---+---+
    
                    +---------------+
    pointerstring:  |       *       |
                    +-------|-------+
                            |           +---+---+---+---+---+---+---+---+
                            +---------> | G | o | o | d | b | y | e |\0 |
                                        +---+---+---+---+---+---+---+---+
    
                    +---------------+      
    pointerstring2: |       *       |
                    +-------|-------+
                            |           +---+---+---+---+---+---+---+---+
                            +---------> | f | o | r |   | n | o | w |\0 |
                                        +---+---+---+---+---+---+---+---+
    

    现在,问题是,你不能在 C 中分配数组。您可以分配指针。您还可以利用特殊规则(“数组和指针之间的等价性”),当您在表达式中使用数组时,您得到的是指向数组第一个元素的指针。

    因此,如果您想将一个字符串作为指针分配给另一个字符串作为指针,则可以:

    pointerstring = pointerstring2;
    

    如果您尝试将一个字符串作为数组分配给另一个字符串作为数组,这是行不通的

    arraystring = arraystring2;     /* WRONG -- compiler complains, attempt to assign array */
    

    如果你想将一个字符串作为数组复制到另一个,你必须调用strcpy(当然你必须担心溢出):

    strcpy(arraystring, arraystring2);
    

    您还可以将字符串作为数组分配给字符串作为指针:

     pointerstring = arraystring;
    

    这是有效的,因为编译器将它完全视为您编写的那样

    pointerstring = &arraystring[0];
    

    最后,如果您尝试将字符串指针分配给字符串数组,这将不起作用,因为您无法分配给数组:

     arraystring = pointerstring;    /* WRONG */
    

    同样,只要您确定字符串适合,您也可以调用 strcpy

    strcpy(arraystring, pointerstring);  /* but worry about overflow */
    

    在您的原始代码中,mname 是一个字符串数组,因此您不能分配给它。你有两个选择:

    1. 使用strcpy 将字符串复制到其中:

      if (mm == 1) { strcpy(mname, "January"); }

    2. mname 声明为 p 指针:

      char *mname;

      ...

      if (mm == 1) { mname = "January"; }


    附录:为了完整起见,我应该再提一组要点。

    当你初始化一个指向字符串的指针时,可以通过以下任一方式:

    char *pointerstring = "Goodbye";
    char * pointerstring2;
    pointerstring2 = "for now";
    

    那些字符串"Goodbye""for now"只读的。你不能修改它们。所以如果你尝试做类似的事情

     strcpy(pointerstring, pointerstring2);    /* WRONG: overwriting constant string */
    

    它不起作用,因为您试图将第二个字符串复制到存储第一个字符串的内存中,但该内存不可写。

    所以在使用数组的时候,不能使用赋值,必须使用strcpy;但是当你使用指针时,你可以使用赋值,你可能无法调用strcpy

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2021-03-23
      • 2023-03-08
      • 2013-07-14
      • 2017-08-04
      • 2016-07-11
      • 2021-12-15
      相关资源
      最近更新 更多