输入功能跳过。应用修复。奇数结果

问题描述 投票:2回答:2

我有一个 简单的程序。 目的只是为了锻炼我刚学到的C语言知识。

请记住,我已经尝试解决了这个问题。剩饭 残存 stdin缓冲区 利用我已有的知识。从我弄清楚换行问题之前所遇到的问题来看,我已经取得了相当大的进展,让这个程序按照我想象的方式运行。这就是我剩下的所有调试和 我被困住了。 当我的 C语言的流利程度是边缘化的。 充其量,我相信这个程序可以很容易地工作。不需要大量的修改。

该程序要求用户选择一个工具,我已经构建了2个简单的工具。这些工具本身工作得很好,但俗气的是,这些工具都是由我自己设计的。挑选字母 "用户界面 我所建造的有一个 虫子 我就是想不通。它通过程序运行 正如第一次预期的那样。第二次。 用于工具选择的变量得到 换成新行 字符,而用户对该变量的输入赋值会被覆盖。因此,程序进入用于工具选择变量的开关结构并激活。

case '\n': 

打印出一个错误信息,表示有一个换行符挡住了去路,然后退出来回到菜单循环的开始。在这个 第三次,程序将再次按照预期工作。 它会继续这样交替运行,直到你通过正常程序运行结束时提供的出口退出程序。

这是对相关代码的直接剪切和粘贴,不包括D_Time(); 和cal(); 函数。如果需要的话,可以随时用变种函数编译和运行,直接看问题。两个都是void函数,一个是简单的2个参数计算器,另一个是通过stdout显示日期和时间。而您有任何其他可以提高我对C语言或这个程序的认识的建议,我都会欣然接受并寻求。我还在学习,虽然指针和微积分让我很不适应,但我会掌握好的。

void clrnl(void)
{
    while (getc(stdin) != '\n');
} /* This is the fix that kind-of but not-really fixes the '\n' problem. Without it, the error message would pop up every time i used the menu, not including the first run. */

void menu(void)
{
    char tool = 1;
    int r = 0;
    while (r != 1)
    {
        printf("\n ---Select a tool.---\n\n ------------------\n\n C = Calculator\n\n D = Date/Time\n\n ");
        tool = getc(stdin);
        clrnl(); /* This seems to be the only line where clrnl(); has a positive effect. */
        switch (tool)
        {
            case 'D':
                printf("\n You selected Date/Time ");
                D_Time();
                r = 1;
                break;
            case 'C':
                printf("\n You selected Calculator ");
                cal();
                r = 1;
                break;
            case 'd':
                printf("\n You selected Date/Time ");
                D_Time();
                r = 1;
                break;
            case 'c':
                printf("\n You selected Calculator ");
                cal();
                r = 1;
                break;
            case '\n':
                printf("\n Error!! -- Newline character detected!! Try again.\n\n");
                r = 0;
                break;
            default:
                printf("\n Error!! -- Unknown. Try again.\n\n");
                r = 0;
                break;
        }
    }
}
int main()
{
    char lx;
    do
    {
        menu();
        printf("\n Enter 'x' to exit.\n\n ");
        scanf(" %c", &lx);
        if (lx != 'x')
        {
            continue;
        }
    }
    while (lx != 'x');
return 0;
}
c newline
2个回答
0
投票

问题是当你输入你的选择时,例如 D如果你按了回车键,就会发生各种情况。如果你是在windows系统上,你的应用程序将接收字符。'D', '\r', '\n'. 在linux上,它将是 'D','\n'. 吞噬掉任何额外的输入。scanf 使用这个简单的技巧。

scanf(" %c*", &lx);

这个... * 格式字符串中的回车和换行字符将被跳过。

这是工具选择的更改代码。

    printf("\n ---Select a tool.---\n\n ------------------\n\n C = Calculator\n\n D = Date/Time\n\n ");
    scanf(" %c*", &tool);

这是退出输入的部分。

    printf("\n Enter 'x' to exit.\n\n ");
    scanf(" %c*", &lx);

你可以进一步把更多的switch case像这样放在一起 以减少代码的重复。

case 'D':
case 'd':
    printf("\n You selected Date/Time ");
    D_Time();
    r = 1;
    break;

这样就可以了,因为后面没有break语句。case 'D',所以如果发生这种情况,代码会继续通过 case 'd': 行到相应的代码中。


2
投票

通常情况下,上下文菜单是不需要等待用户按回车键才能得到选项的,而你的循环则是这样做的.为了在按下相关键时选择选项,而不是等待 "回车",你可以调用操作系统的特定功能。在linux系统下,可以使用以下方法重新配置你的终端 system ("/bin/stty raw") 在进入while循环之前,让事情保持原样。在窗口下考虑 _getch() 而不是getc(stdin).请记住这一点 getchar()和getc() 回报 整数 而不是一个char.这样做,你有一个更加反应灵敏的菜单,你不需要处理额外生成的字符。

© www.soinside.com 2019 - 2024. All rights reserved.