即使使用安全设置(getchar()),也会跳过scanf

即使使用安全设置(getchar()),也会跳过scanf,c,input,stdin,scanf,fflush,C,Input,Stdin,Scanf,Fflush,我知道这个问题被问了上百遍,我已经搜索了所有的可能性,但我想我还不太熟练,不知道这个问题在哪里。我正在编写一个程序,需要用数据(整数和字符串)填充结构。我第一次尝试它时,它跳过了除第一个之外的所有内容,但我没有惊慌,因为我记得在课堂上我需要使用fflush(stdin)来克服这个问题。我搜索过的网站投票反对使用fflush(stdin),因为它有未定义的行为。他们说使用getchar()会占用额外的换行符,从而解决问题。因此,我的代码是: int manNode(){ Item *p; int

我知道这个问题被问了上百遍,我已经搜索了所有的可能性,但我想我还不太熟练,不知道这个问题在哪里。我正在编写一个程序,需要用数据(整数和字符串)填充结构。我第一次尝试它时,它跳过了除第一个之外的所有内容,但我没有惊慌,因为我记得在课堂上我需要使用
fflush(stdin)
来克服这个问题。我搜索过的网站投票反对使用
fflush(stdin)
,因为它有未定义的行为。他们说使用
getchar()
会占用额外的换行符,从而解决问题。因此,我的代码是:

int manNode(){
Item *p;
int helper;
p = (Item*)malloc(sizeof(Item));
printf("Welk type? (Taak:1, Examen:2, Voordracht:3)\n");
scanf("%u",&helper);                           //selecting an itemtype
if (helper < 1 || helper > 3)
{
    printf("wrong value, please try again");
    return 0;
}
getchar();                                     //I've just put getchars everywhere for safety.
p->entrytype = helper-1;
helper = 0;
printf("Vul een naam in:\n");
scanf("%s", p->name);                          //this one fills in fine
getchar();
printf("Vul een vaknaam in: \n");
scanf("%s", p->course);                        //this one gets skipped if I type more than one letter in the last scanf()                
getchar();
printf("Vul een starttijd in:\n");             //From here on out everything gets skipped
p->start = getTijd();
checkTijd(p->start);                           
printf("Vul een eindtijd in: \n");
p->end = getTijd();
checkTijd(p->end);
int manNode(){
项目*p;
int-helper;
p=(项目*)malloc(项目规模);
printf(“Welk类型”(Taak:1,Examen:2,Voordracht:3)\n);
scanf(“%u”,&helper);//选择一个项目类型
如果(辅助对象<1 | |辅助对象>3)
{
printf(“值错误,请重试”);
返回0;
}
getchar();//为了安全起见,我把getchar放在了所有地方。
p->entrytype=helper-1;
helper=0;
printf(“vuleen naam in:\n”);
scanf(“%s”,p->name);//这一个填写很好
getchar();
printf(“vuleen vaknaam in:\n”);
scanf(“%s”,p->course);//如果我在最后一次scanf()中键入了多个字母,则跳过此字母
getchar();
printf(“Vul een starttijd in:\n”);//从这里开始,所有内容都被跳过
p->start=getTijd();
选中TIJD(p->开始);
printf(“vuleen eindtijd in:\n”);
p->end=getTijd();
选中TIJD(p->end);

我知道这有点混乱,但重点放在scanfs和getchar上。
getTijd()
中也有一些scanfs扫描整数,它们也会被跳过。我不知道从这里开始该怎么做。(代码不是不完整的,其余的都是无关的)

你可以定义一个新的getchar

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

#define getchar(x) (scanf("%c", x))

int main ()
{
    char x, y[10];
    getchar(&x);
    scanf("%s", y);
    printf("got %s\n", y);
    return 0;
}
#包括
#包括
#定义getchar(x)(scanf(“%c”,x))
int main()
{
charx,y[10];
getchar&x;
scanf(“%s”,y);
printf(“获得%s\n”,y);
返回0;
}
更新:这可能是一种更好的方法

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

void work_to_do()
{
#define getchar(x) (scanf("%c", x))
    char x, y[10];
    getchar(&x);
    scanf("%s", y);
    printf("got %s\n", y);
#undef getchar
}
int main ()
{
    work_to_do();
    return 0;
}
#包括
#包括
作废工作
{
#定义getchar(x)(scanf(“%c”,x))
charx,y[10];
getchar&x;
scanf(“%s”,y);
printf(“获得%s\n”,y);
#未定义getchar
}
int main()
{
工作要做;
返回0;
}
要解决scanf新行忽略和getchar(但scanf仍然忽略空格)

#包括
#包括
#包括
#包括
#define _getchar()(read(2,NULL,1))//2代表标准错误,我们可以让用户输入一个字符。
作废工作
{   
chary[10];
__getchar();
scanf(“%s”,y);
printf(“获得%s\n”,y);
__getchar();
}
int main()
{
工作要做;
返回0;
}
看看这个很好:
scanf
的工作原理如文件所述。此外,只要理解其功能,scanf也没有任何问题

我创建了您的代码副本并对其进行了提炼,以突出显示您想要做的事情。其余部分您需要自己填写

在此代码中,您需要输入一个数字并按enter键。然后输入一个字符串并按enter键,等等。注意,
fflush(stdout)
语句是K&R标准C实现的一部分。
fflush
强制将缓冲区的内容输出到控制台。这种刷新有助于形成合理的用户/计算机对话框

#include <stdio.h>
main()
{
    char string[100];
    int  helper;

    printf("Welk type? (Taak:1, Examen:2, Voordracht:3)\n");
    fflush(stdout);

    scanf("%d",&helper);    //select an itemtype
    if (helper < 1 || helper > 3)
    {
        printf("wrong value, please try again");
        return 0;
    }

    printf("Vul een naam in:\n");
    fflush(stdout);

    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een vaknaam in: \n");
    fflush(stdout);

    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een starttijd in:\n");
    fflush(stdout);
    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een eindtijd in: \n");
    fflush(stdout);
    scanf("%s", &string[0]);
    printf("\n%s\n", string);
}
#包括
main()
{
字符串[100];
int-helper;
printf(“Welk类型”(Taak:1,Examen:2,Voordracht:3)\n);
fflush(stdout);
scanf(“%d”,&helper);//选择一个项目类型
如果(辅助对象<1 | |辅助对象>3)
{
printf(“值错误,请重试”);
返回0;
}
printf(“vuleen naam in:\n”);
fflush(stdout);
scanf(“%s”和字符串[0]);
printf(“\n%s\n”,字符串);
printf(“vuleen vaknaam in:\n”);
fflush(stdout);
scanf(“%s”和字符串[0]);
printf(“\n%s\n”,字符串);
printf(“vuleen starttijd in:\n”);
fflush(stdout);
scanf(“%s”和字符串[0]);
printf(“\n%s\n”,字符串);
printf(“vuleen eindtijd in:\n”);
fflush(stdout);
scanf(“%s”和字符串[0]);
printf(“\n%s\n”,字符串);
}
这段代码在Eclipse上使用Microsoft C编译器运行

另外,我要强调的是,如果您输入:1 AAA BBB CCC DDD并按enter键,那么
scanf
将执行五次。在本例中,代码将运行到完成

因此,您需要跟踪您的代码逻辑(在本例中是一条直线),以查看如何根据输入的数据调用scanf


希望这有帮助。如果有更多问题,请提问。

你能展示一下
项的结构吗?
scanf
是C语言中最糟糕的解析工具,因为它试图完成两个任务(读取输入并将其分解成若干部分)当片段不完全符合预期时,它会使输入流处于难以确定的状态。
fgets/sscanf
有助于更有力的分工。您必须检查
scanf()
每次使用它时是否成功。当它出错时,它仍会出错。您应该错误检查
getchar()
函数。您还应该通过打印刚刚读取的值进行调试,以确保得到了您认为得到的值。另外,请注意,
fflush(stdin)
是在Windows上定义的,但不是在Unix平台上定义的。请研究创建SSCCE()。此外,您应该真正展示一个示例,说明您在运行程序时所做的操作,以便我们可以看到出现了什么问题。使用fflush(stdout)然后按enter键强制scanf处理stdin缓冲区。请参阅下面的答案。至少,在重新定义它之前,您必须
#undef getchar
。我不认为这是个好主意。最好为宏使用一个替代名称(可能
getchar
#include <stdio.h>
main()
{
    char string[100];
    int  helper;

    printf("Welk type? (Taak:1, Examen:2, Voordracht:3)\n");
    fflush(stdout);

    scanf("%d",&helper);    //select an itemtype
    if (helper < 1 || helper > 3)
    {
        printf("wrong value, please try again");
        return 0;
    }

    printf("Vul een naam in:\n");
    fflush(stdout);

    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een vaknaam in: \n");
    fflush(stdout);

    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een starttijd in:\n");
    fflush(stdout);
    scanf("%s", &string[0]);
    printf("\n%s\n", string);

    printf("Vul een eindtijd in: \n");
    fflush(stdout);
    scanf("%s", &string[0]);
    printf("\n%s\n", string);
}