在C中刷新标准输入缓冲区
这段代码是我正在进行的一个更大项目的简化,它在一个简单的例子中总结了这个问题。我从用户那里获取输入,他们的名字,然后清除缓冲区中不适合C字符串的任何输入。问题是,在输入名称后,用户必须按两次enter键才能让程序响应,而且因为我使用getchar()刷新缓冲区,所以在我创建的循环逻辑中有一个明显的误解。如何防止用户输入两次Enter,换句话说,我遗漏了什么?谢谢在C中刷新标准输入缓冲区,c,user-input,C,User Input,这段代码是我正在进行的一个更大项目的简化,它在一个简单的例子中总结了这个问题。我从用户那里获取输入,他们的名字,然后清除缓冲区中不适合C字符串的任何输入。问题是,在输入名称后,用户必须按两次enter键才能让程序响应,而且因为我使用getchar()刷新缓冲区,所以在我创建的循环逻辑中有一个明显的误解。如何防止用户输入两次Enter,换句话说,我遗漏了什么?谢谢 #include "stdafx.h" #include <stdio.h> #include <string.h&
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 10
int main(void)
{
unsigned char name[BUFFSIZE];
printf("ENTER YOUR NAME: ");
fgets(name, BUFFSIZE, stdin);
name[strcspn(name, "\n")] = '\0';
//flush the input buffer
int flush;
while (flush = getchar() != '\n' && flush != EOF);
printf("Your name is: %s!\n ", name);
printf("Press enter to continue...");
getchar();
return 0;
}
#包括“stdafx.h”
#包括
#包括
#定义大小10
内部主(空)
{
未签名字符名[BUFFSIZE];
printf(“输入您的姓名:”);
fgets(名称、尺寸、标准尺寸);
名称[strcspn(名称,“\n”)]='\0';
//刷新输入缓冲区
int-flush;
while(flush=getchar()!='\n'&&flush!=EOF);
printf(“您的名字是:%s!\n”,名字);
printf(“按回车键继续…”);
getchar();
返回0;
}
我猜只要阅读您的代码,错误就在这里:
while (flush = getchar() != '\n' && flush != EOF);
您希望getchar()
直到输出缓冲区为'\n'或EOF,对吗?然后试试这个:
while (flush = getchar() != '\n' || flush != EOF);
我猜测,只要阅读您的代码,错误就在这里:
while (flush = getchar() != '\n' && flush != EOF);
您希望getchar()
直到输出缓冲区为'\n'或EOF,对吗?然后试试这个:
while (flush = getchar() != '\n' || flush != EOF);
首先,如果没有剩余部分,则不应使用该行的剩余部分,否则将跳过另一行。其次,赋值的优先级低于大多数操作,这意味着
flush=
在getchar()!='\n’&齐平!=EOF
比较分配时的结果时,应添加显式括号:flush=getchar()!='\n'
到(flush=getchar())!='\n'
或者,可以将赋值移到条件外,请参见下文 下面的编辑使用
strlen
获取最终字符,并将赋值移动到循环中
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 10
int main(int argc, char *argv[])
{
char name[BUFFSIZE];
size_t len;
int c;
printf("ENTER YOUR NAME: ");
fgets(name, BUFFSIZE, stdin);
len = strlen(name);
if (name[len - 1] == '\n')
name[len - 1] = '\0';
else
do
c = getchar();
while (c != '\n' && c != EOF);
printf("Your name is: %s!\n ", name);
printf("Press enter to continue...");
getchar();
return 0;
}
#包括
#包括
#定义大小10
int main(int argc,char*argv[])
{
字符名[BUFFSIZE];
尺寸透镜;
INTC;
printf(“输入您的姓名:”);
fgets(名称、尺寸、标准尺寸);
len=strlen(名称);
如果(名称[len-1]='\n')
名称[len-1]='\0';
其他的
做
c=getchar();
而(c!='\n'&&c!=EOF);
printf(“您的名字是:%s!\n”,名字);
printf(“按回车键继续…”);
getchar();
返回0;
}
首先,如果没有剩余部分,则不应使用该行的剩余部分,否则将跳过另一行。其次,赋值的优先级低于大多数操作,这意味着flush=
在getchar()!='\n’&齐平!=EOF
比较分配时的结果时,应添加显式括号:flush=getchar()!='\n'
到(flush=getchar())!='\n'
或者,可以将赋值移到条件外,请参见下文 下面的编辑使用
strlen
获取最终字符,并将赋值移动到循环中
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 10
int main(int argc, char *argv[])
{
char name[BUFFSIZE];
size_t len;
int c;
printf("ENTER YOUR NAME: ");
fgets(name, BUFFSIZE, stdin);
len = strlen(name);
if (name[len - 1] == '\n')
name[len - 1] = '\0';
else
do
c = getchar();
while (c != '\n' && c != EOF);
printf("Your name is: %s!\n ", name);
printf("Press enter to continue...");
getchar();
return 0;
}
#包括
#包括
#定义大小10
int main(int argc,char*argv[])
{
字符名[BUFFSIZE];
尺寸透镜;
INTC;
printf(“输入您的姓名:”);
fgets(名称、尺寸、标准尺寸);
len=strlen(名称);
如果(名称[len-1]='\n')
名称[len-1]='\0';
其他的
做
c=getchar();
而(c!='\n'&&c!=EOF);
printf(“您的名字是:%s!\n”,名字);
printf(“按回车键继续…”);
getchar();
返回0;
}
程序中的问题是您没有区分两种情况:a)用户的输入适合缓冲区,b)输入不适合缓冲区。这些情况的区别在于缓冲区中是否存在换行符。覆盖该字符时,该信息将被销毁:
fgets(name, BUFFSIZE, stdin);
name[strcspn(name, "\n")] = '\0';
我们需要的是:
size_t nlcspn = strcspn(name, "\n");
bool incomplete = name[nlcspn] == 0;
name[nlcspn] = 0;
现在我们有一个complete
标记要测试。只有当此标志通知输入不包含换行符时,我们才能继续并使用一个小循环完成fgets
的“get line”操作,该循环扫描直到收到换行符。(在这种情况下,一些错误恢复可能也是一个好主意,比如通知用户输入太长,并创造一个机会来纠正)
另一件需要注意的事情是,
fgets
返回一个应该检查的值。如果返回空指针,则表示流在使用任何输入之前结束。问题是在这种情况下,fgets
不会向数组中放入任何内容。数组保留其以前的值,该值可能是以前读取的输入,也可能是由于未初始化的内容而导致的不确定值(“垃圾”)。程序中的问题是您没有区分两种情况:a)用户的输入适合缓冲区,b)输入不适合。这些情况的区别在于缓冲区中是否存在换行符。覆盖该字符时,该信息将被销毁:
fgets(name, BUFFSIZE, stdin);
name[strcspn(name, "\n")] = '\0';
我们需要的是:
size_t nlcspn = strcspn(name, "\n");
bool incomplete = name[nlcspn] == 0;
name[nlcspn] = 0;
现在我们有一个complete
标记要测试。只有当此标志通知输入不包含换行符时,我们才能继续并使用一个小循环完成fgets
的“get line”操作,该循环扫描直到收到换行符。(在这种情况下,一些错误恢复可能也是一个好主意,比如通知用户输入太长,并创造一个机会来纠正)
另一件需要注意的事情是,fgets
返回一个应该检查的值。如果返回空指针,则表示流在使用任何输入之前结束。问题是在这种情况下,fgets