在同一个程序中使用scanf和fgets?

wes*_*bos 6 c scanf

我需要做以下事情:

int main(void) {
char a,b,cstring;

printf("please enter something");
scanf("%c %c",&a,&b);
prinf("thanks, now some more");
fgets(cstring,35,stdin);

}
Run Code Online (Sandbox Code Playgroud)

问题是每当我从scanf输入第一个变量时,它都会跳到程序的末尾.我该如何做多个输入?

Jon*_*ler 7

第一个问题是scanf()读取两个字符,但之后不读取换行符.

这意味着你fgets()读取换行符并完成.

你很幸运你的程序没有崩溃.你告诉fgets()它它正在获得一个包含35个字符的数组,但是你传递的是字符(而不是字符的地址,而不是传递数组).这也告诉我们你没有包括#include <stdio.h>(scanf()根据C标准scanf()你不能在没有原型的情况下可靠地使用),并且你没有启用足够的警告编译,或者没有足够重视编译器告诉你的内容.

您应该收到编译器警告.例如,GCC 4.6.0说:

/usr/bin/gcc -g -I/Users/jleffler/inc -std=c99 -Wall -Wextra -Wmissing-prototypes \
     -Wstrict-prototypes -Wold-style-definition xxx.c
xxx.c: In function ‘main’:
xxx.c:7: warning: implicit declaration of function ‘prinf’
xxx.c:8: warning: passing argument 1 of ‘fgets’ makes pointer from integer without a cast
Run Code Online (Sandbox Code Playgroud)

而且,该死,我完全没有注意到的拼写错误prinf()printf(),直到我试图链接和编译器揉我的鼻子在里面说"不知道什么prinf()是!".

如果你的编译器至少没有给出第二个警告,那么给自己一个更好的编译器.


评论:

如何阻止它读取后的换行符?

问题不在于停止scanf()阅读新行; 问题实际上是如何使它读取它以便fgets()在下一行输入中获得清晰的运行.它实际上是非常棘手的 - 我很少使用的一个原因scanf()(但我经常使用sscanf()).这可以完成简单输入的工作:

#include <stdio.h>
int main(void)
{
    char a,b,cstring[35];

    printf("please enter something");
    scanf("%c %c%*c", &a, &b);
    printf("thanks, now some more");
    fgets(cstring, 35, stdin);
    printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

%*c而不会有任何分配给它读取一个多余的字符(换行符)(这是因为*).但是,如果第二个非空白后有多个字符,则无济于事.我可能会写一个循环来读取换行符:

#include <stdio.h>
int main(void)
{
    char a,b,cstring[35];
    int c;

    printf("please enter something");
    scanf("%c %c", &a, &b);
    while ((c = getchar()) != EOF && c != '\n')
        ;
    printf("thanks, now some more");
    fgets(cstring, 35, stdin);
    printf("OK: I got %c and %c and <<%s>>\n", a, b, cstring);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,getchar()返回a int而不是a char.这可靠地丢弃第一行输入上的所有内容.它还显示了如何回显您所读取的内容 - 这是调试的一个重要部分.