Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中刷新标准输入缓冲区_C_User Input - Fatal编程技术网

在C中刷新标准输入缓冲区

在C中刷新标准输入缓冲区,c,user-input,C,User Input,这段代码是我正在进行的一个更大项目的简化,它在一个简单的例子中总结了这个问题。我从用户那里获取输入,他们的名字,然后清除缓冲区中不适合C字符串的任何输入。问题是,在输入名称后,用户必须按两次enter键才能让程序响应,而且因为我使用getchar()刷新缓冲区,所以在我创建的循环逻辑中有一个明显的误解。如何防止用户输入两次Enter,换句话说,我遗漏了什么?谢谢 #include "stdafx.h" #include <stdio.h> #include <string.h&

这段代码是我正在进行的一个更大项目的简化,它在一个简单的例子中总结了这个问题。我从用户那里获取输入,他们的名字,然后清除缓冲区中不适合C字符串的任何输入。问题是,在输入名称后,用户必须按两次enter键才能让程序响应,而且因为我使用getchar()刷新缓冲区,所以在我创建的循环逻辑中有一个明显的误解。如何防止用户输入两次Enter,换句话说,我遗漏了什么?谢谢

#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