0

I am trying to write some records (patient info) into a .dat file using C. The patient info contains the National ID no., name, gender and the telephone no.

Here's my code:

#include<stdio.h>

int main(void)
{
char order = 'y';
char nic[12];
char name[10];
char gender = ' ';
char tel[10];

FILE *fp;
fp = fopen("patientdetails.dat", "w");

if (fp == NULL)
{
    printf("Couldn't open file\n");
    return -1;
}
else
{
    printf("Do you want to enter record (y/n): ");
    scanf("%c", &order);

    while (order == 'y' || order == 'Y')
    {
        printf("Enter nic no.: ");
        scanf("%s", nic);

        printf("Enter name: ");
        scanf("%s", name);

        printf("Enter gender (m/f): ");
        scanf(" %c", &gender);

        printf("Enter tel no.: ");
        scanf("%s", tel);

        fprintf(fp, "%s %s %c %s", nic, name, gender, tel);

        printf("Do you want to enter record (y/n): ");
        scanf(" %c", &order);
    }
    fclose(fp);
}

return 0;
}

However, when I enter the info into the .dat file the gender shows up as a symbol instead and I just can't get around it.

.dat file image. Gender shows as symbol not m for male

edit:

This is my terminal input:

Do you want to enter record (y/n): y
Enter nic no.: 200007102766
Enter name: aruna
Enter gender (m/f): m
Enter tel no.: 0779426698
Do you want to enter record (y/n): n

The m for male, in the gender input shows up as a diamond with a question mark.

Hey, I wrote a c program to read my .dat file and it seems to work now. Thanks!

Adrian Mole
  • 30,672
  • 69
  • 32
  • 52
  • Maybe `"%s %s %c %s"` -> `"%s %s %c %s\n"`. Anyway please [edit] and show the patientdetails.dat file in your question as text. – Jabberwocky May 05 '20 at 11:21
  • 3
    I tried your code and the gender showed up fine in the file. Perhaps provide specifically in detail what you entered when you ran the program. – lurker May 05 '20 at 11:21
  • Candidates: 1) `char nic[12]; char name[10]; char tel[10];` too small (double their sizes) 2) Spaces in a name 3) **not checking** `scanf()` return value. Post some sample input data here. – chux - Reinstate Monica May 05 '20 at 11:23
  • Using `scanf("%s", nic);` is bad/worse than [`gets()`](https://stackoverflow.com/q/1694036/2410359). Use a _width_ limit: `scanf("%11s", nic);` – chux - Reinstate Monica May 05 '20 at 11:28

1 Answers1

2

In the sample data that you show in the image, your nic and tel data appear to be too long to fit into their assigned variables - this causes undefined behaviour!

If you need to store 12 actual characters in a char[n] string, you need to make n at least 13, so that there is room for the required nul-terminator.

So you will need to make both nic and tel larger arrays:

char order = 'y';
char nic[13]; // 12 chars PLUS the nul-terminator
char name[10];
char gender = ' ';
char tel[11]; // 10 digits PLUS the nul-terminator
//...

You should also prevent the scanf calls from attempting to read too many characters for each string, by specifying a number in the %s format specifier; like this, for example (and similarly for the others):

     scanf("%12s", nic); // Will stop reading after 12 chars have been scanned!

However, with this in place, any 'extra' characters given by the user will be left in the input buffer, and will thus 'overflow' into the next scanf call. You can prevent this by 'flushing' the input stream after each read. The most portable way to flush the STDIN stream, as described here, is to define a macro like the following, somewhere before your main function, then just add INFLUSH after each scanf call. (There also are a number of other ways to effectively 'flush' the input stream, as discussed in the linked Q/A.)

#define INFLUSH { int c;  while ((c = getchar()) != '\n' && c != EOF); }

And you would use it this like this:

    scanf("%10s", tel); INFLUSH // Don't need semicolon after INFLUSH!
Adrian Mole
  • 30,672
  • 69
  • 32
  • 52
  • @Constalation "it doesnt seem to work" lacks information. What was seen? what was expected? Same as before? – chux - Reinstate Monica May 05 '20 at 11:31
  • Hey, Reinstate Monica, thank you for your response. I wrote a c program to read my .dat file and the gender seemed to show up. It works now. Thanks, and I'll make an edit! –  May 05 '20 at 11:40
  • @Constalation Glad it worked! But please read the extra information I've added in the edit. – Adrian Mole May 05 '20 at 11:47
  • Hey @AdrianMole thanks for the extra info, I made the adjustments to the char arrays, and I will surely read the extra info! –  May 05 '20 at 11:51