控制 c 导致打印垃圾

标签 c mingw

我正在制作一个小的测试程序,它演示了一个粗糙的控制台界面。

该程序是一个低于标准的典型获取行、响应程序,它甚至不识别“退出”,并希望您通过按 control-c 强制退出。在 Mingw32 上完成。

令我困惑的是,当按下控制键 c 时。程序在退出前显示垃圾。

例如:

<client> Welcome to Concept Program.
<client> type h for help menu.
<you> meep
<client> 'meep' is not a recognized command.
<you> *ctrl-c*
<you> <client> 'meep' is not a recognized command.

这个程序的代码是:

#include <stdio.h>

int main(int argc, char **argv)
{
    puts("<client> Welcome to Concept Program.");
    puts("<client> type h for help menu.");

    while (1) {
        char msg[200];
        printf("<you> ");
        gets(msg);
        if (strcmp(msg, "h") == 0) {
            puts("<client>");
            puts("-help menu-");
            puts("h: shows this menu");
            puts("-----------");
        } else {
            printf("<client>'%s' is not a recognized command.\n", msg);
        }
    }

    return 0;
}

我想知道如何阻止它在这种情况下打印垃圾,如果可能的话,解释为什么会发生这种情况。

我知道这是一个愚蠢的问题,但我们将不胜感激!


注意/2022:我收到通知后重新访问了这个旧程序,发现有几个明显的缺陷(其中一些是吹毛求疵和不真实的):

  1. 程序没有#include <string.h>尽管使用了 strcmp。
  2. 程序没有setvbuf(stdout, (char *)0, _IONBF, 0)也不fflush ,这使得不同终端/tty 上的输出不一致。
  3. 最重要的是 gets 的所有潜在问题,它被认为已弃用,甚至可能在较新的编译器中被删除。

即使使用原始代码,原始错误也不会出现在我当前的机器上。

这里是略微改进的代码,没有完全重写:

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

int main(int argc, char **argv)
{
    setvbuf(stdout, (char *)0, _IONBF, 0);
    puts("<client> Welcome to Concept Program.");
    puts("<client> type h for help menu.");

    for (;;) {
        char msg[200];

        printf("<you> ");
        scanf("%200s", msg);
        
        /* scanf ALWAYS leaves "\n" in stdin after reading. Clear stdin. */
        {
            int ch;
            
            ch = getchar();
            while ((ch != '\n') && (ch != EOF)) {
                ch = getchar();
            }
        }
        
        if (!strcmp(msg, "h")) {
            puts("<client>");
            puts("-help menu-");
            puts("h: shows this menu");
            puts("-----------");
        } else {
            printf("<client>'%s' is not a recognized command.\n", msg);
        }
    }

    return 0;
}

最佳答案

改为这样写,您需要检查 fgets 的返回值,如果按下 ctrl-c 它将返回 NULL。

   while (1) {
        char msg[200];
        printf("<you> ");
        if (fgets(msg,sizeof(msg),stdin) != NULL)
        {
          if (strcmp(msg, "h") == 0) 
          {
              puts("<client>");
              puts("-help menu-");
              puts("h: shows this menu");
              puts("-----------");
          } 
          else 
          {
              printf("<client>'%s' is not a recognized command.\n", msg);
          }
        }
    }

关于控制 c 导致打印垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23326193/

相关文章:

c - 从文件中删除一条记录

c++ - 如何获取ethtool设置?

c - 通过指向 void 的指针传递值

c - 尽管一切看起来都正确,但仍然得到 'curl/curl.h: No such file or directory'

c++ - 如何从 Linux for Windows 交叉编译 SDL 2

c - Windows 显示驱动程序 Hook ,64 位

c - 如何在 `c`中获取 `GCC`程序的抽象语法树

c - make 找不到 sys/signal.h

c++ - 在 C++ 中使用库 "xtensor-blas"时出错

python - Cython hello world 示例在 Windows 上不起作用