0

I have been struggling with this little bit of my code for a very long time now and I need some help. I tried a lot to figure this out, but my output always differed from what I expected. I am trying to convert a binary file that has multiple lines into a text file. The problem has to do with my while loop because removing the while loop and running the code with a file that has only one line works perfectly. My code is as follows:

void binaryToText(char *inputFile, char *outputFile){

int sID; 
float gpa;
char firstName[256], lastName[256];
unsigned char firstNameLen, lastNameLen;

FILE *finp = fopen(inputFile, "rb");
FILE *fout = fopen(outputFile, "w");

if((finp != NULL)&&(fout != NULL)){

while(!feof(finp)){
    fread(&firstNameLen, 1, 1, finp);
    fread(firstName, firstNameLen, 1, finp);
    firstName[firstNameLen] = '\0';
    fread(&lastNameLen, 1, 1, finp);
    fread(lastName, lastNameLen, 1, finp);
    lastName[lastNameLen] = '\0';
    fread(&sID, 4, 1, finp);
    fread(&gpa, 4, 1, finp);
    fprintf(fout, "%s %s %d %1.1f\n", firstName, lastName, sID, gpa);
    }
}
fclose(finp);
fclose(fout);
}

My output is supposed to look like:

mary smith 1 3.9
george washington 2 4.0
james bond 7 3.2

My output with feof is:

mary smith 1 3.9
george washington 2 4.0
james bond 7 3.2
james bond 7 3.2

I tried using fread in the form 'while (nmemb == (nret = fread(str, sizeof *str, nmemb, finp))) != NULL`, but my output was still wrong. Please how can I correctly make a loop that gives me the desired output?

Chibuikem
  • 51
  • 1
  • 6
  • Ah, I see you are back. Check `while(fgets(str, fileLen, finp) != NULL)` as `fileLen` is the _length of the file_ so there will be only one read. And then, following this reading, what is there left to read????? – Paul Ogilvie Feb 12 '17 at 10:34
  • You could have found this problem if you had checked the return value of `fread`. – Paul Ogilvie Feb 12 '17 at 10:37
  • Please @Paul Ogilvie how would I check the return value of fread and how would that help me solve the problem? I also think there is nothing left to be read after the while loop reads the file. I am probably wrong and could be why I cannot figure out how to do this properly. – Chibuikem Feb 12 '17 at 11:01
  • @Chibuikem just check if `EOF` is set with `feof()` ... – UrbiJr Feb 12 '17 at 11:05
  • @UrbiJr when you say check is `EOF` is set with `feof`, I tried to check it by doing something like `feof(finp) != 0` is this wrong. From what I understand `feof` returns a nonzero value if I try to read after the file has ended but returns 0 otherwise. Is that a way to check if `EOF` is set with `feof`? – Chibuikem Feb 12 '17 at 11:16
  • @Chibuikem Basically `feof()` returns `0` when `EOF` is set, *in other words* when the *end of file* is reached. If this has already happened, then `EOF` must be already set and `feof()` still works as expected. However, there's no reason why you should read past the end of the file, if you *wrote* and *read* it right. At least, this never happened to me, and `feof()` always did his job. – UrbiJr Feb 12 '17 at 11:26
  • Please add the `while` part of the version with `feof()` so I can see what's the matter – UrbiJr Feb 12 '17 at 11:31
  • Hey mate, sorry, I made a few oversights and I completely forgot that actually *you have to add* the `'\0'` terminator when using `fread()` to read strings. This is because basically I usually use structs. However, I'm updating my answer and show you the final and correct version. – UrbiJr Feb 12 '17 at 11:43
  • Ok @Chibuikem now you can see the correct code in my answer. Please test it, then you could check my answer as solution. – UrbiJr Feb 12 '17 at 11:49
  • __BUG__: `fread(&gpa, sizeof (int), 1, finp);` this reads a thing the size of an int into a variable of type float. Note that the file must have a binary float, not a textype such as `"3.25"`. The read will not convert text to binary. Use fscanf for that. – Paul Ogilvie Feb 12 '17 at 13:15

0 Answers0