1
votes

Currently I'm doing my C programming homework. I'm facing a problem that I need to add some records to a text file using fprintf, then display out all the records within the file using fscanf. But here the display problem. It only skip the first character in the text, and display the rest. Example in the textfile,

hello haha 400 500 60
hello2 haha2 500 600 70

We need to fscanf this file into display in command prompt. But in result show me...

ello haha 400 500 60
hello2 haha2 500 600 70

The rest of characters is okay, but for the first character, it skipped. So this is my codes.

Fscanf's part

if ((ch = fgetc(fp)) != EOF){
while(fscanf(fp,"%s %s %d %d %d",code,name,&cost,&price,&stock) == 5)
{
  printf("%-20s %-20s %-20d %-20d %-20d\n",code,name,cost,price,stock);
}
}else{
  printf("Record not found in the stock database.\n");
  puts("");
}

Fprintf's part

fprintf(fp,"%s %s %d %d %d\n",code,name,cost,price,stock);

So, how to read the first character ?

3
You read the first character with fgetc. - Paul Hankin
your if ((ch = fgetc(fp)) reads the first character. This is why it is skipped - Aserre
It is sufficient to check that the return value of fscanf is correct. The fgetc is redundant. - Tom Fenech
to adress your edit : the way you read the file (with while(fscanf ...)) is ok. You should change your if ((ch = fgetc(fp)) though. Try something like if (fp){ ... } or if(feof(fp)) {...} instead - Aserre
If you want to keep your current code structure, check out ungetc function. It allows returning (at least) 1 char to a FILE* stream. - hyde

3 Answers

1
votes

Your fgetc(fp) read the first h of the first hello, so now the file pointer is at e of hello. Further calls of your fscanf will read from e onwards. A simple soultion would be to add a printf("%c", ch) just above your while loop in your if condition. I.e,

if ((ch = fgetc(fp)) != EOF){
    printf("%c", ch);
    while(fscanf(fp,"%s %s %d %d %d",code,name,&cost,&price,&stock) == 5)
    {
      printf("%-20s %-20s %-20d %-20d %-20d\n",code,name,cost,price,stock);
    }
}else{
    printf("Record not found in the stock database.\n");
    puts("");
}
0
votes

The problem that you are having is that fgetc() is pulling your first character, as mentioned in the comment. In order to get the first character, you either need to store this character somewhere and append it to your output at the beginning, or else use a different method to check that the first character is not EOF.

Note that you could also cause definite problems if your first item was only one character long--Then your fscanf() would no longer have a 1st string to look at.

0
votes
if ((ch = fgetc(fp)) != EOF){
    ungetc(ch, fp);
    while(fscanf(fp,"%s %s %d %d %d",code,name,&cost,&price,&stock) == 5)