Linked list in C with fgets()

老子叫甜甜 提交于 2019-12-12 22:07:53

问题


I'm having issues with my code skipping the first question in the second data structure. I'm pretty sure it's because the gets(), but not sure. I think I tried fgets(), but it still was giving me issues. Why?

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

#define NumberOfActresses 5

typedef struct Actress
{
char *name, *placeofbirth, *haircolor;
int age;
float networth;
struct Actress *next;

} Actress;

void PopulateStruct(Actress *node)
{
node->name = (char *) malloc(sizeof(char) * 50);
node->placeofbirth = (char *) malloc(sizeof(char) * 50);
node->haircolor = (char *) malloc(sizeof(char) * 50);

printf("Please enter the name of the actress/actor: ");
gets(node->name);
printf("Please enter the actress/actor place of birth: ");
gets(node->placeofbirth);
printf("Please enter the actress/actor hair color: ");
gets(node->haircolor);
printf("Please enter the actress/actor age: ");
scanf("%d", &node->age);
printf("Please enter the actress/actor networth: ");
scanf("%f", &node->networth);
}

void DisplayStruct(Actress *head)
{
Actress *crawler;

crawler = head;

while(crawler != NULL)
{
    printf("The name of the actress/actor is: %s\n", crawler->name);
    printf("The place of birth for the actress/actor is: %s\n",       crawler->placeofbirth);
    printf("The hair color of the actress/actor is: %s\n", crawler->haircolor);
    printf("The actress/actor age is: %d\n", crawler->age);
    printf("The networth for the actress/actor is %f\n", crawler->networth);
    crawler = crawler->next;
}
}

int main()
{
int i;
Actress *head = (Actress *) malloc(sizeof(Actress)), *crawler;

crawler = head;

 for (i = 0; i < NumberOfActresses; i++)
    {
    PopulateStruct(crawler);
    if (i == 2)
        crawler->next = NULL;
    else
        crawler->next = malloc(sizeof(Actress));

    crawler = crawler->next;
}

crawler = NULL;

DisplayStruct(head);

return 0;
}

回答1:


Mixing fgets and scanf always turns out badly. The reason is that scanf will leave the newline character in the input stream, and the following fgets will therefore read an empty line. And using gets is just plain wrong.

The solution is to always read the input with fgets, and then parse the input with sscanf as needed. For those cases where sscanf is not needed, i.e. the input is a string, you can use strcspn to remove the newline from the buffer.

int PopulateStruct(Actress *node)
{
    char buffer[100];

    printf("Please enter the name of the actress/actor: ");
    if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
        return 0;
    buffer[strcspn(buffer,"\n")] = '\0';
    if ( (node->name = malloc(strlen(buffer) + 1)) == NULL )
        return 0;
    strcpy( node->name, buffer );

    // ditto for place of birth and hair color

    printf("Please enter the actress/actor age: ");
    if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
        return 0;
    if ( sscanf( buffer, "%d", &node->age ) != 1 )
        return 0;

    printf("Please enter the actress/actor networth: ");
    if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
        return 0;
    if ( sscanf( buffer, "%lf", &node->networth ) != 1 )
        return 0;

    return 1;
}

Oh, and I changed the networth from float to double. A float has only 6 or 7 digits of precision, and that's not nearly enough for the net worth of an actress/actor.



来源:https://stackoverflow.com/questions/36731181/linked-list-in-c-with-fgets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!