4

I created a small program to input some records to a file.

#include<stdio.h>

int main(void)
{
    FILE *fp;
    //opening a file to write
    fp = fopen("try.rec","w");
    if(fp == NULL)
    {
        printf("\nSorry! Couldn't Create File");
        exit(-1);
    }
    int id = 1;
    char name[300] = "Cipher", address[300] = "Virtual Street", phone[20] = "223322212";
    fprintf(fp,"%d, %s, %s, %s", id, name, address, phone);
    fclose(fp);
    return 0;
}

Now, it does good work there is not error in this. But i also made a small program to read that record:

#include<stdio.h>

int main(void)
{
    FILE *fp;
    fp = fopen("try.rec","r");
    if (fp == NULL)
    {
        printf("Could not Access File. :(");
        return -1;
    }
    int id;
    char name[300], add[300], phone[20];
    fscanf(fp, "%d , %s , %s , %s",&id, &name, &add, &phone);
    fclose(fp);
    printf("\nDetails from File try.rec\n---------------------------\nID: %d \nName: %s \nAddress: %s \nPhone: %s \n", id, name, add, phone);
    return 0;
}

But when printing the third string it prints garbage values. I dug deeper and found out that when i replace "Cipher" with "Cipher " (having one extra space at last) in my first program and run it, then the third string in second program outputs only Virtual (and nothing after space) and then the fourth string is garbage again.

So, is there any other good alternative ways to put and get the string from file in C. Or Am I doing wrong thing in either of my program?

Anticipating Your Help!

Thanks in Advance.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
cipher
  • 2,414
  • 4
  • 30
  • 54

2 Answers2

6

The problem is that the %s format tells fscanf to read all non-whitespace characters, so

fscanf(fp, "%d , %s , %s , %s",&id, &name, &add, &phone);

will read "Cipher," into name (aside: the correct argument there would have been name instead of &name), then the next conversion fails because the fscanf doesn't find a ','.

With the space after the "Cipher ", the scanning stops after the space is found, and then the next scan stops at the space between "Virtual" and "Street", then again there's no ',' as required by the format and further conversions fail.

You should check the return value of fscanf to verify that the appropriate number of conversions have been done, and handle the situation accordingly if too few succeeded.

Here, you could use tha %[^,] character set format to scan in your strings,

fscanf(fp, " %d , %[^,] , %[^,] , %s", &id, name, add, phone);
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Thanks. It works. But, May i ask what is `%[^,]` . Looks like a Regualr Expression – cipher Nov 22 '12 at 12:27
  • 1
    It's a character set format, looks like a regex, but is much simpler. You can list either accepted characters - `%[abcdef0123456789]` for example for hexadecimal digits - or rejected characters, if the first character inside the brackets is `'^'` - `%[^\n \t]` will stop at a newline, space or tab. – Daniel Fischer Nov 22 '12 at 12:29
1

Check the return value of fscanf, it returns the number of successful conversions. Also, you tell the fscanf function to separate tokens on whitespace (the blanks in the format string) so a string containing whitespace (like "Virtual Street") is considered two tokens.

I recommend you read the whole line using fgets and then use strtok to separate the string on the commas.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621