-1

This is my code:

struct Patient{
   char name[50];
   char gender ; // M:male , F:female
   unsigned age ;
   unsigned Systole;
   unsigned Diastole;
};
//blah blah blah
struct Patient P[3];
for(i=0 ; i<3 ; i++){
   printf("\nPATIENT%d\n",i+1);
   printf("Name:");
   gets(P[i].name);
   printf("Gender(F=female , M=male):");
   scanf("%c",&(P[i].gender));
   printf("Systole:");
   scanf("%u",&(P[i].Systole));
   printf("Diastole:");
   scanf("%u",&(P[i].Diastole));
   printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole, P[i].Diastole);
   }

This is my output:

PATIENT1
Name:Samantha
Gender(F=female , M=male):F
Systole:120
Diastole:90

Samantha F 120 90

PATIENT2
Name:Gender(F=female , M=male):Jack
Systole:Diastole:
 J 4718656 131072

PATIENT3
Name:Gender(F=female , M=male):Michael
Systole:Diastole:
ack M 16454 2
Normal:0

And as you can see (I print after getting each struct index data) I have problems getting input from user. What is the problem?

EDIT. I changed the code (due to advises) to:

for(i=0 ; i<3 ; i++){
   printf("\nPATIENT%d\n",i+1);
   printf("Name:");
   scanf("%s", &(P[i].name));
   printf("Gender(F=female , M=male):");
   scanf("%c",&(P[i].gender));
   printf("Systole:");
   scanf("%u",&(P[i].Systole));
   printf("Diastole:");
   scanf("%u",&(P[i].Diastole));
   printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole, P[i].Diastole);
        }

But output is still distorted:

PATIENT1
Name:Alison
Gender(F=female , M=male):Systole:F
Diastole:
Alison
 436170816 4044120064

PATIENT2
Name:Gender(F=female , M=male):Systole:Jack
Diastole:
F
 4456512 131072

PATIENT3
Name:Gender(F=female , M=male):Systole:Sandy
Diastole:
Jack
Alireza Mohamadi
  • 751
  • 1
  • 6
  • 22

4 Answers4

1

The scanf("%u",&(P[i].Diastole)); gets a integer, but leaves a new line (from the user entering the number and pressing enter)

On the second iteration through the loop, gets(P[i].name); reads that left over newline and puts everything else off from that point.

You need to handle reading the last new line character (or potentially \r\n), or you could use gets or better yet fgets to read in each line input and using sscanf or atoi etc to get the values from it (when a number is needed).

lostbard
  • 5,065
  • 1
  • 15
  • 17
0

The function gets does not store the newline, so you have to use:

scanf(" %c", &(P[i].gender))

Note the space which will skip blank spaces including newline You should avoid using the gets function, try to use only scanf this should be:

scanf(" %49[^\n]%*c", P[i].name)

See this post for more information on how the scanf works

Putting all togheter the working code is:

for(i=0 ; i<3 ; i++){
   printf("\nPATIENT%d\n",i+1);
   printf("Name:");
   scanf(" %49[^\n]%*c", P[i].name);
   printf("Gender(F=female , M=male):");
   scanf(" %c",&(P[i].gender));
   printf("Systole:");
   scanf("%u",&(P[i].Systole));
   printf("Diastole:");
   scanf("%u",&(P[i].Diastole));
   printf("\n%s %c %u %u\n", P[i].name, P[i].gender, P[i].Systole,   P[i].Diastole);
}

The first scanf now consumes also any newline from the previous iteration.

Community
  • 1
  • 1
terence hill
  • 3,354
  • 18
  • 31
0

Your main problem is this statement:

scanf("%c",&(P[i].gender));

The c conversion specifier won't skip over any leading whitespace in the input stream (such as the newline character following a previous entry, which gets doesn't consume), so you're picking up the newline character for gender, and that's throwing off everything else that follows.

To fix this, put a blank space before the %c:

scanf(" %c",&(P[i].gender));

The blank space tells scanf to consume all leading whitespace.

Also, don't use gets - it was deprecated in C99 TC3 and has been removed from the C2011 specification altogether. It will introduce a point of failure in your code. Use fgets instead:

fgets( P[i].name, sizeof P[i].name, stdin );

Unlike gets, fgets will consume and store the newline character into the target buffer if there's room, so you'll need to check for and remove it, something like the following:

char *newline = strchr( P[i].name, '\n' );
if ( newline )
  *newline = 0;
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Finally I've got the true and neat answer:

The scanf function removes whitespace automatically before trying to parse things other than characters. The character formats (primarily %c) are the exception; they don't remove whitespace.

Since I was getting a char for gender, it was causing problems. Finally I realized using getch() is the best solution because it doesn't put anything into buffer and returns immediately. Also getch() is non-standard, but it is present in my case.
So finally this is my code:

for(int i=0 ; i<3 ; i++){
        printf("\nPatient%d",i+1);
        printf("\nName:");
        scanf("%s", P[i].name);
        printf("Age:");
        scanf("%u", &(P[i].age));
        printf("Gender(F=female , M=male):");
        P[i].gender = getchar();
        printf("\nSystole:");
        scanf("%u",&(P[i].Systole));
        printf("Diastole:");
        scanf("%u",&(P[i].Diastole));
    }

Also I edited question title because it was misleading. Thanks everyone for answering efforts.

Alireza Mohamadi
  • 751
  • 1
  • 6
  • 22