如何在结构中正确使用fgets?

时间:2023-01-08 20:54:41

I can't work out what's the problem with my code. Here's my code:

我无法弄清楚我的代码有什么问题。这是我的代码:

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

#define N 20

typedef struct _dog {
    char dogName[N],ownerName[N];
    int dogAge;
} Dog;

int main() {
    //Dynamic array
    int size;
    printf("Number of dogs: ");
    scanf("%d", &size);
    Dog *dog = (Dog*)malloc(sizeof(Dog)*size);
    printf("\n");
    //Input
    int i;
    printf("Please provide the data: [dogName][ownerName][dogAge] :\n");
    for(i=0;i<size;i++) {
        fgets(dog[i].dogName, sizeof(dog[i].dogName), stdin);
        fgets(dog[i].ownerName, sizeof(dog[i].ownerName), stdin);
        scanf("%d", &dog[i].dogAge);
    }
    //Output
    printf("\nYou provided the following data:\n");
    for(i=0;i<size;i++) {
        printf("Dog Name: %s\nOwner Name: %s\nDog Age: %d\n", dog[i].dogName, dog[i].ownerName, dog[i].dogAge);
    }

    free(dog);
    return 0;
}

The task is pretty easy, you have to make a database but the dogs and owners can have two or more names, so that's why i try to use fget. But the output looks awful: (And the first Dog name part is usually blank)

任务很简单,你必须建立一个数据库,但狗和所有者可以有两个或更多的名称,这就是为什么我尝试使用fget。但输出看起来很糟糕:(第一个狗名部分通常是空白的)

You provided the following data:
Dog Name: 

Owner Name: Doggy 1

Dog Age: 0
Dog Name: Big Dick

Owner Name: 2

Dog Age: 0

I've read this but didn't help me.

我读过这篇文章却没有帮助我。

The input I used:

我使用的输入:

Doggy 1
Big Dick
2
Doggy 2

It's ended after Doggy 2.

它在Doggy 2之后结束。

2 个解决方案

#1


11  

You are leaving a newline from your last scanf() which is a valid input for the fgets(). Change

您将离开上一个scanf()的换行符,该换行符是fgets()的有效输入。更改

scanf("%d", &size);

to

scanf("%d%*c", &size);

to consume and discard the trailing newline due to the press of ENTER key after entering the number of dogs.

在输入狗的数量后按ENTER键消耗并丢弃尾随换行符。

The same goes for the dogAge variable scanning, too, inside the lop.

同样适用于dogAge变量扫描,也就是在lop内部。

Related, quoting the C11 standard, chapter §7.21.6.2, fscanf()

相关的,引用C11标准,章节§7.21.6.2,fscanf()

Trailing white space (including new-line characters) is left unread unless matched by a directive. [...]

除非与指令匹配,否则尾部空格(包括换行符)将保持未读状态。 [...]

so, the newline ('\n'), the trailing white space, is left unread in the input buffer.

因此,新行('\ n')(尾随空格)在输入缓冲区中未被读取。

#2


3  

Add a getchar() after the scanf(...) calls.

在scanf(...)调用之后添加getchar()。

As in the other answer(s) mentioned. scanf consumes the recognized characters according to format, but leaves the newline \n in stdin. With getchar you consume it and subsequent reads from stdin should not get confused.

与提到的其他答案一样。 scanf根据格式使用识别的字符,但在stdin中保留换行符\ n。使用getchar,你可以使用它,并且后​​续的stdin读取不应该混淆。

#1


11  

You are leaving a newline from your last scanf() which is a valid input for the fgets(). Change

您将离开上一个scanf()的换行符,该换行符是fgets()的有效输入。更改

scanf("%d", &size);

to

scanf("%d%*c", &size);

to consume and discard the trailing newline due to the press of ENTER key after entering the number of dogs.

在输入狗的数量后按ENTER键消耗并丢弃尾随换行符。

The same goes for the dogAge variable scanning, too, inside the lop.

同样适用于dogAge变量扫描,也就是在lop内部。

Related, quoting the C11 standard, chapter §7.21.6.2, fscanf()

相关的,引用C11标准,章节§7.21.6.2,fscanf()

Trailing white space (including new-line characters) is left unread unless matched by a directive. [...]

除非与指令匹配,否则尾部空格(包括换行符)将保持未读状态。 [...]

so, the newline ('\n'), the trailing white space, is left unread in the input buffer.

因此,新行('\ n')(尾随空格)在输入缓冲区中未被读取。

#2


3  

Add a getchar() after the scanf(...) calls.

在scanf(...)调用之后添加getchar()。

As in the other answer(s) mentioned. scanf consumes the recognized characters according to format, but leaves the newline \n in stdin. With getchar you consume it and subsequent reads from stdin should not get confused.

与提到的其他答案一样。 scanf根据格式使用识别的字符,但在stdin中保留换行符\ n。使用getchar,你可以使用它,并且后​​续的stdin读取不应该混淆。