C开关,如何修复多个默认打印?

C switch, how to fix multiple default prints?

提问人:Ronja Oksanen 提问时间:8/22/2023 最后编辑:Jean-Baptiste YunèsRonja Oksanen 更新时间:8/24/2023 访问量:74

问:

如果我给我的程序这个:

abcdefghijklmnopqrstuvwxyz

它的回答是这个?!

Invalid command a
Invalid command c
Invalid command e
Invalid command g
Invalid command i
Invalid command k
Invalid command m
Invalid command o
Invalid command q
Invalid command s
Invalid command u
Invalid command w
Invalid command y

知道为什么只有其他每个字母都会收到我的默认消息,以及为什么有这么多而不是只有一个,我该如何解决这个问题,以便无论我输入多少无效字符,我都只能收到一条默认消息?

这是我代码的那部分:

while (1) {
  scanf("%c", &command);
  getchar();

  switch (command) {
  case 'A': // Adds a new entry to the program database.
    if (scanf("%s %f", name, &price) != 2) {
      printf("A should be followed by exactly 2 arguments.\n");
      // while (getchar() != '\n'); // Clear the input buffer
    } else {
      getchar(); // Consume the newline character
      addGame(&games, &numGames, name, price); // Pass pointer to games
    }
    break;
  case 'B': // Buy game command, which sells a specified number of games
    if (scanf("%s %d", name, &count) != 2 || count <= 0) {
      getchar(); // Consume the newline character
      printf("Number of bought items cannot be less than 1.\n");
    } else {
      getchar(); // Consume the newline character
      buyGame(games, numGames, name, count);
    }
    break;
  case 'L': //Prints a list of the program database into the standard output
    printDatabase(games, numGames);
    break;
  case 'W': //Writes the program database into a text file
    scanf("%s", filename);
    getchar();
    saveToFile(games, numGames, filename);
    break;
  case 'O': //Loads the database from the specified text file
    scanf("%s", filename);
    getchar();
    loadFromFile(&games, &numGames, filename); // Pass pointer
    break;
  case 'Q': //Quits the program after releasing the program database
    releaseMemory(games, numGames);
    return 0;
  case '\n': //Not sure i need this?
    break;
  default:
    printf("Invalid command %c\n", command);
  }
}

如果有人认为需要,我可以发送更多代码:)

c char switch-statement scanf getchar

评论

2赞 Retired Ninja 8/22/2023
scanf(" %c", &command);在前面放一个空格以跳过前导空格。这可能会有所帮助。scanf() 将换行符保留在缓冲区中%c
3赞 Some programmer dude 8/22/2023
请缩进您的代码,这将使它更容易阅读和理解它的作用。
0赞 Some programmer dude 8/22/2023
并且不需要整个“消费换行符”业务。请参阅@RetiredNinja的评论,了解删除所有这些调用的简单方法。请注意,只有 (和 ) 才需要格式中的前导空格,而不需要任何其他自动执行此操作的格式。getchar()%c%[
1赞 Jonathan Leffler 8/22/2023
@Someprogrammerdude:也不占用空格,但它是一种奇怪的转换规范。%n
0赞 Ronja Oksanen 8/22/2023
谢谢大家的回答:)回答“请缩进您的代码”我试图粘贴我的代码,但是“添加您的问题”页面不允许我发布,直到我像那样说唱*d)

答:

0赞 Vlad from Moscow 8/22/2023 #1

在 while 循环的开头,你有

while (1) {
scanf("%c", &command);
getchar()
//...

因此,当您输入这样的符号序列时

abcdefghijklmnopqrstuvwxyz

然后,scanf 的调用读取一个字符,例如“a”,getchar 的下一个调用读取下一个字符“b”。由于命令“a”无效,则 scanf 的下一次调用将读取下一个字符“c”,getchar 的调用将读取字母“d”,依此类推。你所做的就是你所得到的。

而不是这两个调用

scanf("%c", &command);
getchar()

您只能使用一个 like 调用scanf

scanf(" %c", &command);

注意格式字符串中的前导空格。它允许跳过空格字符,包括换行符。如果输入无效,则应清除标签下的输入缓冲区,例如'\n'default

while ( getchar() != '\n' );

scanf( "%*[^\n]" );

并删除代码其他地方的调用。getchar

评论

0赞 Ronja Oksanen 8/22/2023
非常感谢!我认为这将解决我的问题:)我两个月前才开始学习 C 语言,所以我真的不擅长这个,我相信这里的每个人都会嘲笑我^^
0赞 Vlad from Moscow 8/22/2023
@RonjaOksanen 完全没有。不客气:)
0赞 Some programmer dude 8/22/2023 #2

您一次只阅读一个字符,而不是整行。这就是为什么你会得到“这么多,而不仅仅是一个”。

要阅读整行,请使用。如果需要,还可以添加仅输入一个字符的验证。fgets

你之所以只得到每两个字符的报告错误,只是因为之后的误导性调用。调用将读取例如,然后调用将读取 .等等。getcharscanf("%c", &command)scanfagetcharb

0赞 Luis Colorado 8/24/2023 #3

在您的循环中,在顶部:

  scanf("%c", &command);  /* read one char into command */
  getchar();              /* skip the next char, ignoring it */

你读一个字符,然后删除下一个字符。这就是读取替代字符并生成该输出的原因,因为输入字符是小写的,而您只检查一些大写字符。commandgetchar()