0

Hi I’m doing a test program in C File I/O for my System software (assemblers,loader etc ) course , my problem is the last line is read twice , I remember my teacher told me this is due to some slight syntax or bug I missed ,I forgot what it is , please take a look and help me quick.

Program

#include<stdio.h>
#include<stdlib.h>
//read from source.txt and write to output.txt

int main()
{
FILE *f1=fopen("source.txt","r");
FILE *f2=fopen("output.txt","w");
int address;
char label[20],opcode[20];
while(!feof(f1))//feof returns 1 if end of file
{
fscanf(f1,"%s\t%s\t%d",label,opcode,&address);
printf("%s\t%s\t%d\n",label,opcode,address);
fprintf(f2,"%s\t%s\t%d\n",label,opcode,address);
}
int check=fclose(f1);
int check2=fclose(f2);
printf("close status %d %d",check,check2);
return 0;
}

source.txt

NULL    LDA     4000
ALPHA   STA     5000
BETA    ADD     4020// I stopped right here, DID NOT PRESS 'ENTER' , so that ain’t the issue

output.txt

NULL    LDA     4000
ALPHA   STA     5000
BETA    ADD     4020
BETA    ADD     4020

//last line twice

output in terminal

NULL    LDA     4000
ALPHA   STA     5000
BETA    ADD     4020
BETA    ADD     4020

//last line twice

I don't want the last line to be printed or written twice , what am I doing wrong , help!

Chandru
  • 1,306
  • 13
  • 21
Sainath S.R
  • 3,074
  • 9
  • 41
  • 72
  • 2
    `!feof(f1)` is wrong. EOF will be one more loop after reading the last line from occurring in the reading of scanf. – BLUEPIXY Oct 26 '14 at 07:33
  • 1
    You should test the result of [fscanf(3)](http://man7.org/linux/man-pages/man3/fscanf.3.html); also testing `feof` is meaningless before any read. – Basile Starynkevitch Oct 26 '14 at 07:33
  • @BasileStarynkevitch I am not well versed in C & File I/O, I have a Java Background, can you elaborate in simple terms for me , and what exactly does feof() Test and return ? – Sainath S.R Oct 26 '14 at 07:36
  • @BLUEPIXY if so then what will the last fscanf() call read,it will real NULL right ? , then why its printing again – Sainath S.R Oct 26 '14 at 07:38
  • Read documentation of [fscanf(3)](http://man7.org/linux/man-pages/man3/fscanf.3.html) and of [feof(3)](http://man7.org/linux/man-pages/man3/feof.3.html). Notice that `feof` is meaningful only *after* a (failed) read operation (like `fscanf`, `fgets`, `fgetc`...) – Basile Starynkevitch Oct 26 '14 at 07:39
  • 2
    @BLUEPIXY To put it simply , I have 3 lines ,third line is read , EOF not yet set , therefore fourth time loop is entered ,fourth time fscanf() tries ,Fails ,sets EOF indicator , but previous value in buffer or temp String remains , its printed , ,Next Loop test fails , stops , Am I correct ? – Sainath S.R Oct 26 '14 at 07:46
  • 2
    @DroidIcs That's right. – BLUEPIXY Oct 26 '14 at 07:51
  • @BLUEPIXY Changed , works now `while(!feof(f1)) { if(fscanf(f1,"%s\t%s\t%d",label,opcode,&address)==3) { printf("%s\t%s\t%d\n",label,opcode,address); fprintf(f2,"%s\t%s\t%d\n",label,opcode,address); } }` – Sainath S.R Oct 26 '14 at 07:53
  • do as like perreal's way if the same thing. – BLUEPIXY Oct 26 '14 at 07:57
  • @BLUEPIXY I removed the feof() , thanks! – Sainath S.R Oct 26 '14 at 08:02

1 Answers1

2

You can use the return value of fscanf, which should be equal to the number of items successfully scanned:

while(fscanf(f1,"%s\t%s\t%d",label,opcode,&address) == 3) {
    printf("%s\t%s\t%d\n",label,opcode,address);
    fprintf(f2,"%s\t%s\t%d\n",label,opcode,address);
}
perreal
  • 94,503
  • 21
  • 155
  • 181