2

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;
}
humbleCoder
  • 463
  • 1
  • 5
  • 18

1 Answers1

2

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.

user3386109
  • 34,287
  • 7
  • 49
  • 68