我有一个 简单的程序。 目的只是为了锻炼我刚学到的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;
}
问题是当你输入你的选择时,例如 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':
行到相应的代码中。
通常情况下,上下文菜单是不需要等待用户按回车键才能得到选项的,而你的循环则是这样做的.为了在按下相关键时选择选项,而不是等待 "回车",你可以调用操作系统的特定功能。在linux系统下,可以使用以下方法重新配置你的终端 system ("/bin/stty raw")
在进入while循环之前,让事情保持原样。在窗口下考虑 _getch()
而不是getc(stdin).请记住这一点 getchar()和getc() 回报 整数 而不是一个char.这样做,你有一个更加反应灵敏的菜单,你不需要处理额外生成的字符。