while循环在C中得到两次()

时间:2013-05-30 11:29:36

标签: c while-loop gets

我知道这个while循环问题很常见,它通常是由输入流中的换行引起的。但是,我无法修复我的while循环,我真的不明白为什么会发生这种情况。

考虑以下示例:

 int main()
 {
   int option = -1;
   char buffer[100];
   while (option != 10)
    {
     while(printf("Enter menu choice: \n"), gets(buffer), option < 0)
           {
             some code here dealing with buffer and assigning input to option...
           }
     printf("something\n");
     }
    return 0;
  }

忽略此代码的实现(例如将输入存储为整数而不是字符串等),因为它只是我的while循环的简化版本。关注我的是我必须在实际经历循环之前输入两次数字。

输出:

进入菜单选项: 1

进入菜单选项: 1

所有灯都亮起 灯光设置:1111 1111 1111 1111

我不确定为什么会发生这种情况......谢谢!

更新:谢谢你的回答。我通过重写我的while()条件

来修复代码
while(printf("\nEnter menu choice: \n"), gets(buffer),  option = checkMenuOption(buffer), option < 0 && strcmp(buffer, ""));

2 个答案:

答案 0 :(得分:2)

我可以建议您使用fgets代替gets吗?它更安全,可用于防止缓冲区溢出。

另外,我已经重写了一下你的代码,这会做你感兴趣的吗?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int option = -1;

    char buffer[100];

    while (option != 10)
    {
        printf("Enter menu choice: \n");

        fgets(buffer, 100, stdin); /* get input from the standard input
                                      and save it in the buffer array */

        option = atoi(buffer); /* convert input to integer */
    }

    return 0;
}

如果用户键入“10”,程序将退出:

$ ./a.out 
Enter menu choice: 
10
$

如果你想在这里保留旧代码,那就是:

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int option = -1;
    char buffer[100];
    while (option != 10)
    {
        while(printf("Enter menu choice: \n"), gets(buffer), option = atoi(buffer), option < 0)
        {

        }
        printf("something\n");
    }
    return 0;
}

问题是你没有在循环条件中分配option任何东西。在第一次测试期间,option仍然不是10,它只在身体中变为10.在第一次运行选项被分配10(或者你输入的任何内容)之后,while循环仍然没有评估它和这就是为什么它再次打印语句并要求你输入一个值。

您可以像这样重写循环来测试我的声明(确保代码更新option仍在正文中):

while(option < 0 && printf("Enter menu choice: \n") && gets(buffer))

最后,不要使用逗号,因为用逗号分隔的语句将始终执行(我假设这不是你想要的,在其他情况下它可能完全没问题),它只是列表的最后一个成员进行真/假测试。看看this

答案 1 :(得分:0)

在评估while之前,printf()和gets()都在option测试范围内。

事实上,根据当前行为,您实际上不必输入两次数字:您必须输入一次数字,然后输入任何内容,以便get()返回。

编辑:我添加了一些有关如何运行的详细信息:

  • 指令指针到达while语句的最开头,开始评估其条件
    • 调用printf()
    • 调用gets()
    • 评估option < 0,这是真的。
  • while声明的正文
    • 代码解析字符串,将option设置为大于零的值。
  • 指令指针循环回到评估条件
    • 调用printf()
    • 调用gets()
    • 评估option < 0,这是假的。
  • while循环终止
    • 致电printf("something\n");

这里可以看到缓冲区一旦被gets()填充,只能在第一次迭代中被代码读取,而在第二次迭代中被忽略。