我必须输入两次才能使getchar()正常工作

我必须输入两次才能使getchar()正常工作,c,fgets,getchar,C,Fgets,Getchar,我使用getchar()创建了trobule。我必须输入两次代码才能正常工作。我这样编写代码: #include<stdio.h> #include<stdlib.h> #define MAX_LEN 20 struct part { int number; char name[MAX_LEN + 1]; } part_1; int main(void){ int ch, th; for (;;) { printf

我使用getchar()创建了trobule。我必须输入两次代码才能正常工作。我这样编写代码:

#include<stdio.h>
#include<stdlib.h>
#define MAX_LEN 20

struct part {
    int number;
    char name[MAX_LEN + 1];
} part_1;
 
int main(void){
    int ch, th; 

    for (;;) {
        printf("Enter operation code: ");
        while ( (ch = getchar()) != '\n' && ch != EOF){
            switch (ch){

                case 'i': 
                printf("Enter part number: ");
                scanf("%d",&part_1.number);

                while ( (th = getchar()) != '\n'); /*I use this to remove newline character*/

                printf("Enter part name: ");
                fgets(part_1.name,MAX_LEN,stdin);
                break; 
                
                case 'q': exit(0);
            }
        }
    }
}   
Enter operation code: i
Enter part number: 1
Enter part name: test
Enter operation code: i
Enter operation code: a
Enter operation code: b
Enter operation code: c
Enter operation code: i
Enter part number: 1234
Enter part name: hello
Enter operation code: d
Enter operation code: e
Enter operation code: f
Enter operation code:
Enter operation code:
Enter operation code: q
但是,我必须输入两次代码才能正常工作:

Enter operation code: i
Enter part number: 1
Enter part name: test
-> /* This is where I have to press 'Enter' twice */
Enter operation code: i

当您输入零件名称并按enter键时,fgets将返回并从switch语句中断开并返回while语句:
while((ch=getchar())!='\n'&&ch!=EOF){
。然后需要再按一次enter键,使条件
为false
,以便它返回到
for
-语句,在该语句中它将再次打印“enter operation code:”

基本上,您希望找到一种方法,在读取部件名时,从switch语句和while语句中分离出来

现在,我不确定您是否希望它正常工作,但您可以尝试将while语句替换为:

[...]
    for (;;) {
        printf("Enter operation code: ");
        ch = getchar();
        if (ch != '\n') getchar();  // remove linebreak from stdin
        switch (ch){
[...]
这样,输出将如下所示:

#include<stdio.h>
#include<stdlib.h>
#define MAX_LEN 20

struct part {
    int number;
    char name[MAX_LEN + 1];
} part_1;
 
int main(void){
    int ch, th; 

    for (;;) {
        printf("Enter operation code: ");
        while ( (ch = getchar()) != '\n' && ch != EOF){
            switch (ch){

                case 'i': 
                printf("Enter part number: ");
                scanf("%d",&part_1.number);

                while ( (th = getchar()) != '\n'); /*I use this to remove newline character*/

                printf("Enter part name: ");
                fgets(part_1.name,MAX_LEN,stdin);
                break; 
                
                case 'q': exit(0);
            }
        }
    }
}   
Enter operation code: i
Enter part number: 1
Enter part name: test
Enter operation code: i
Enter operation code: a
Enter operation code: b
Enter operation code: c
Enter operation code: i
Enter part number: 1234
Enter part name: hello
Enter operation code: d
Enter operation code: e
Enter operation code: f
Enter operation code:
Enter operation code:
Enter operation code: q

当您输入零件名称并按enter键时,fgets将返回并从switch语句中断开并返回while语句:
while((ch=getchar())!='\n'&&ch!=EOF){
。然后需要再按一次enter键,使条件
为false
,以便它返回到
for
-语句,在该语句中它将再次打印“enter operation code:”

基本上,您希望找到一种方法,在读取部件名时,从switch语句和while语句中分离出来

现在,我不确定您是否希望它正常工作,但您可以尝试将while语句替换为:

[...]
    for (;;) {
        printf("Enter operation code: ");
        ch = getchar();
        if (ch != '\n') getchar();  // remove linebreak from stdin
        switch (ch){
[...]
这样,输出将如下所示:

#include<stdio.h>
#include<stdlib.h>
#define MAX_LEN 20

struct part {
    int number;
    char name[MAX_LEN + 1];
} part_1;
 
int main(void){
    int ch, th; 

    for (;;) {
        printf("Enter operation code: ");
        while ( (ch = getchar()) != '\n' && ch != EOF){
            switch (ch){

                case 'i': 
                printf("Enter part number: ");
                scanf("%d",&part_1.number);

                while ( (th = getchar()) != '\n'); /*I use this to remove newline character*/

                printf("Enter part name: ");
                fgets(part_1.name,MAX_LEN,stdin);
                break; 
                
                case 'q': exit(0);
            }
        }
    }
}   
Enter operation code: i
Enter part number: 1
Enter part name: test
Enter operation code: i
Enter operation code: a
Enter operation code: b
Enter operation code: c
Enter operation code: i
Enter part number: 1234
Enter part name: hello
Enter operation code: d
Enter operation code: e
Enter operation code: f
Enter operation code:
Enter operation code:
Enter operation code: q


注意:函数:
getchar()
返回一个
int
,而不是
char
我已按照您的建议编辑了我的代码,并尝试再次运行代码,但问题尚未解决。关于:
while((ch=getchar())!='\n')
代码还需要检查EOFI是否已更新代码。您能帮我找出代码的问题吗?请不要修改原始问题,而是添加编辑。否则注释将变得毫无意义,从而使问题的未来读者感到困惑注:函数:
getchar()
返回一个
int
,而不是
char
我已按照您的建议编辑了我的代码,并尝试再次运行代码,但问题尚未解决。关于:
while((ch=getchar())!=“\n”)
代码还需要检查EOFI是否已更新代码。您能帮我找出代码的问题吗?请不要修改原始问题,而是添加编辑。否则注释将变得毫无意义,从而使问题的未来读者感到困惑。我想
scanf
将留下一个新行字符字符后面,所以我使用
while(th=getchar())!='\n'
吃那个换行符,这样我就可以使用
fgets
将信息插入
part\u 1.name
。我指的是
printf之后的while语句(“输入操作代码:”)
。请注意,
fgets
确实读取换行符,因此
part_1.name
将包含一个换行符。我按照您的建议执行,效果很好。但是,如果我像这样更改我的旧代码:
fgets(part_1.name,MAX_LEN,stdin);getchar();
并删除
scanf(“%d”,“part_1.number”)之后的-while语句
,我将获得与您的代码相同的结果。您能解释一下原因吗?我不是100%确定,因为我已经有一段时间没有在C中读取stdin了,但我认为这是因为
scanf
可以读取和丢弃字符,直到它找到要查找的字符类型为止,在本例中是一个数字。如果您在更改后打印
part\u 1.number
的内容?如果我遵循您的代码,我确实成功地打印了
part\u 1.number
part\u 1.name
的内容。但是,如果我将
getchar
放在
fgets
之后,打印
part\u 1.name
将不返回任何内容。但是,我现在理解了这个问题
fgets
将吃掉换行符,而
getchar
将等待我输入某个内容。之后,它将读取一个字符并将换行符留给下一个while循环。这就是为什么我看起来像你一样获得了结果,但事实上,它只是“看起来像那样,但不是那样”.现在我对C的理解更清楚了。非常感谢您的帮助。我想
scanf
会留下一个换行符,所以我使用
while(th=getchar())!='\n'
来吃那个换行符,这样我就可以使用
fgets
将信息插入
part\u 1.name
。我指的是
printf之后的while语句(“输入操作代码:”)
。请注意,
fgets
确实读取换行符,因此
part_1.name
将包含一个换行符。我按照您的建议执行,效果很好。但是,如果我像这样更改我的旧代码:
fgets(part_1.name,MAX_LEN,stdin);getchar();
并删除
scanf(“%d”,“part_1.number”)之后的-while语句
,我将获得与您的代码相同的结果。您能解释一下原因吗?我不是100%确定,因为我已经有一段时间没有在C中读取stdin了,但我认为这是因为
scanf
可以读取和丢弃字符,直到它找到要查找的字符类型为止,在本例中是一个数字。如果您在更改后打印
part\u 1.number
的内容?如果我遵循您的代码,我确实成功地打印了
part\u 1.number
part\u 1.name
的内容。但是,如果我将
getchar
放在
fgets
之后,打印
part\u 1.name
将不返回任何内容。但是,我现在理解了这个问题
fgets
将吃掉换行符,
getchar
将等待我输入内容。之后,它将读取一个字符并离开换行符