【问题标题】:Why does the message print twice?为什么消息打印两次?
【发布时间】:2013-08-24 05:07:07
【问题描述】:

我正在为 C 创建一个简单的井字游戏,这是一个我遇到问题的特定函数。这应该让用户选择“X”或“O”,并且它适用于大多数艺术。但是,如果我输入了错误的符号,它会打印以下语句: “无效符号,请重新输入:”两次。

为什么以及如何解决这个问题?

char assign(void)                                 
{
      char user;

      printf("Would you like to be X or O (Enter your choice): ");
      user=getchar();
      while(user != 'X' && user != 'x' && user != 'O' && user != 'o')
      {
             printf("Invalid symbol, please re-enter: ");  
             user=getchar();
      }
      if(user == 'O' || user == 'o')        return('O');
      else if(user == 'X' || user == 'x')   return('X');     
}

【问题讨论】:

标签: c while-loop


【解决方案1】:

问题原因与换行符有关

以这种方式使用scanf(),而不是使用getchar()

scanf(" %c", &user);

【讨论】:

  • 像魅力一样工作!这比公认的答案要好。谢谢。
【解决方案2】:

这是因为当您使用getchar 时,它会返回下一个字符,但会将换行符留在输入缓冲区中。所以下一个 getchar 返回那个换行符。

您还应该小心,因为 getchar 实际上返回的是 int 而不是 char

您可以通过另一个getchar 来解决这个问题,或者像这样使用scanf

scanf("%c ", &user);

注意上述格式中c 后面的空格,它告诉scanf 读取并忽略尾随空格。

你也可以读一行,例如fgets 然后在该行上使用简单的sscanf,则不需要额外的空间。

【讨论】:

  • 但更好的是使用intuser
  • 使用另一个 getchar() 是什么意思?但是谢谢,我会尽快接受。
  • @C_Beginner_Learner 一个 getchar 获取您想要的字符,一个获取(并丢弃)换行符。
  • @JoachimPileborg 谢谢,它现在可以工作了,只是在我重新输入有效符号后它会打印一个奇怪的“u”符号。
  • %c 后面的空格可能不是个好主意; scanf() 在您输入另一个非空白字符之前不会停止寻找输入。使用" %c"(之前的空格)读取任何空格,例如从前一个输入行剩余的换行符,然后返回第一个不是空格的字符。
【解决方案3】:

你可以像这样修复它,例如:

char assign(void)
{
      char user;
      char throwaway_newline;

      printf("Would you like to be X or O (Enter your choice): ");
      user=getchar();
      throwaway_newline = getchar();
      while(user != 'X' && user != 'x' && user != 'O' && user != 'o')
      {
             printf("Invalid symbol, please re-enter: ");  
             user=getchar();
             throwaway_newline = getchar();
      }
      if(user == 'O' || user == 'o')        return('O');
      else if(user == 'X' || user == 'x')   return('X');     
}

【讨论】:

  • 一旦我这样做,它不会重复行,但是,一旦我重新输入有效符号,它就会打印一个奇怪的“u”符号(仅供参考,我在throwaway_newline = getchar();之后添加了一个中断语句@
  • @C_Beginner_Learner:老实说,这不是一个非常好的解决方案(例如,您不能输入多个符号)我不确定您的 'u' 字符来自哪里。
  • 如果在循环中添加了break,并且字符不正确,那么您会在没有实际返回值的情况下跌出函数底部,因此您可能会得到u 作为垃圾非返回值。 break(由@C_Beginner_Learner 添加)不合适。未经检查地使用getchar() 可能会导致问题;如果你得到EOF,你有一个无限循环。 else if 子句可能会比普通的else 更好,甚至没有elseif (user == 'O' || user == 'o') return('O'); return('X');
  • 但没有中断,“无效符号,请重新输入:”语句在输入符号后不断重复(正如您所说的无限循环)。那么我能做什么呢? @JonathanLeffler(除了将 else if 更改为 else)
  • 您可以通过在第一个响应中输入换行符或输入空白和o(比如)加上换行符来将此代码驱动到循环中。第二次迭代将换行符读入user,然后等待更多输入。我认为最简单的解决方案是使用while (scanf(" %c", &user) == 1 && user != 'X' && user != 'x' && user != 'O' && user != 'o') { printf("Invalid symbol. Please re-enter O or X: "); 读取字符,然后使用循环int c; while ((c = getchar()) != EOF && c != '\n') ; 读取并包括换行符(同时注意EOF)。
【解决方案4】:

您的输入缓冲区中有一个换行符。

当您按下一个不是 [xX] 且不是 [oO] 的字符并在其后添加换行符时。 getchar 实际上可以看到 2 个字符(换行符和无效字符)

您可能希望使用fgets,而不是依赖字符输入并每次都使用 2 个 getchar() 调用忽略换行符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多