【问题标题】:String Comparison Loop issues字符串比较循环问题
【发布时间】:2014-07-07 18:26:56
【问题描述】:

为了好玩,我正在用 C 语言制作一个小文字冒险游戏,但遇到了一个小问题。

char cobra_weapon[5];
int cobra_sword_bonus = 3;
int cobra_mace_bonus = -2;
int cobra_attack_score;
int cobra_main_hand;
int cobra_off_hand = shield;



do {
    fgets(cobra_weapon, 5, stdin);

    if (strcmp(cobra_weapon,"sword") == 0)
        cobra_main_hand = sword + cobra_sword_bonus;
    else if (strcmp(cobra_weapon,"mace") == 0)
        cobra_main_hand = mace + cobra_mace_bonus;
    else
        printf ("You entered %s. Please enter either sword or mace.\n", cobra_weapon);
} while (strcmp(cobra_weapon,"sword") != 0 || strcmp(cobra_weapon,"mace") != 0);

我遇到的问题是当我输入正确的字符串时 strcmp 没有捕捉到条件。即使我输入剑或狼牙棒,它仍然会继续循环。我确信这将是一些我没有看到的简单的东西,但我们将不胜感激。

【问题讨论】:

  • fgets 也可能包含换行符,所以sword 真的是sword\n\0
  • 如果在 if 中添加了一个 break,则不需要在 while 循环和 if 语句中进行检查。
  • 我认为你可以使用调试器
  • 只需使用 strncmp 而不是 strcmp 并且只比较您要匹配的字符串的长度。

标签: c string loops comparison


【解决方案1】:

首先,有几点需要考虑:

char cobra_weapon[5];

这没有足够的内存来存储“sword\0”。将其更改为:

char cobra_weapon[6];  

...甚至更好,将其更改为更大的维度:

char cobra_Weapon[63+1]; 

那么,也改变一下:

fgets(cobra_weapon, 5, stdin);

到:

fgets(cobra_weapon, sizeof(cobra_weapon), stdin);

最后,请记住 fgets() 喜欢将 '\n' 字符附加到输入字符串。因此,删除换行符很重要。也许这样的事情会更好:

do {
   char *cp;

   while(NULL == fgets(cobra_weapon, sizeof(cobra_weapon), stdin))
      /* LOOP */ ; 

   cp=strchr(cobra_weapon, '\n');
   if(cp)
      *cp='\0';

   ...

只要有剑,-或- 狼牙棒,就一直循环:

while (strcmp(cobra_weapon,"sword") != 0 || strcmp(cobra_weapon,"mace") != 0);

或:

while(strcmp(cobra_weapon,"sword") || strcmp(cobra_weapon,"mace"));

只要有-no-sword-and--no-mace就一直循环:

while(strcmp(cobra_weapon,"sword") && strcmp(cobra_weapon,"mace"));

只要有剑和狼牙棒,就一直循环:

while(0 == strcmp(cobra_weapon,"sword") && 0 == strcmp(cobra_weapon,"mace"));

只要有剑或狼牙棒就一直循环:

while(0 == strcmp(cobra_weapon,"sword") || 0 == strcmp(cobra_weapon,"mace"));

【讨论】:

    【解决方案2】:
    char cobra_weapon[5];
    ...
    fgets(cobra_weapon, 5, stdin);
    

    “剑”需要 6 个字符(记住尾随 '\0'

    改为:

    char cobra_weapon[6];
    

    在使用fgets 时,还要删除尾随的\n

    char cobra_weapon[6];
    char *p;
    ...
    fgets(cobra_weapon, sizeof(cobra_weapon), stdin);
    if ((p = strchr(cobra_weapon, '\n')) != NULL) { 
        *p = '\0'; /* remove newline */
    }
    ...
    

    【讨论】:

    • 相当肯定 fgets 会在用户点击回车时保留\n。所以你需要 7 个字符:sword + \n + \0.
    • @abelenky,fgets() 函数应该从流中读取字节到 s 指向的数组中,直到 n-1 个字节被读取,或者 是读取并传输到s
    • 是的:就是这样:如果换行符被读取并传输,那么在结果缓冲区中有一个换行符\n
    • @abelenky,不,if sizeof(cobra_weapon) == 6 并且您键入“sword”,换行符不会被转移。 ideone
    • 如果您输入"mace" 会怎样? (4 个字符)...然后 cobra_weapon 将是 "mace\n\0"(6 个字符),它不会与 "mace\0" 成功比较。
    【解决方案3】:

    您正在使用 fgets 获取输入,当您按 Enter 时,它会保留换行符 (\n)。

    因此,对于一个 4 个字母的单词,例如“mace”,您需要至少保留 6 个空格:

    mace + \n + \0
      4  +  1 +  1 == 6.
    

    这也是您的strcmp 失败的原因。尝试将“mace”与“mace\n”进行比较不会导致匹配。它们不是同一个字符串!

    【讨论】:

    • 不,“狼牙棒”只需要 5 个字符(“剑”只需要 6 个字符),因为 fgetsstops 在 n-1,当然你需要 char[6] 并跳过 \n存储和比较两个字符串,看看我的答案
    【解决方案4】:

    如果您的意图是在成功获得swordmace 后跳出循环,那么除了将cobra_weapon 长度增加1 的其他cmets 之外,您可以简单地使用break

    char cobra_weapon[6];
    ...
    
    do {
        fgets(cobra_weapon, sizeof (cobra_weapon), stdin);
    
        if (strcmp(cobra_weapon,"sword") == 0) {
            cobra_main_hand = sword + cobra_sword_bonus;
            break;
        }
        else if (strcmp(cobra_weapon,"mace") == 0) {
            cobra_main_hand = mace + cobra_mace_bonus;
            break;
        }
        else
            printf ("You entered %s. Please enter either sword or mace.\n", cobra_weapon);
    } while (strcmp(cobra_weapon,"sword") != 0 || strcmp(cobra_weapon,"mace") != 0);
    

    【讨论】:

      猜你喜欢
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 2019-05-04
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多