1

I am having trouble copying from a binary file and writing to a text file. I have written a program that is capable of copying from a text file and writing to a binary file but I cannot do the reverse.

Here is my function that I am having issues with:

void CopyBin2Text(char* rafname, char* txtname)
{

FILE * fraf = fopen(rafname,"rb");
FILE * ftxt = fopen(txtname,"r+");

//READ FROM BINARY FILE
struct PERSON p;
int ByteOfBin;


printf("ID \t NAME \t\t BALANCE \n");
printf("---------------------------------------\n");

when I run my program it stops here after printing the above statement

  while(!feof(fraf))
  {
       fscanf(fraf, "%d %s %f", &p.ID, p.name, &p.balance);

    ByteOfBin = ((p.ID/10-1)*sizeof(p));
    fseek(ftxt,ByteOfBin, SEEK_SET);
    fwrite((char *)&p, sizeof(p), 1, ftxt);

  }


fclose(fraf);
fclose(ftxt);
}

Another issue that I have noticed is that the text file becomes to large to open. The result is that I have to delete the text file and create it again. Can anyone explain what is causing this to occur?

JonSnow
  • 67
  • 3
  • 14
  • You say that the file you read is binary, but then you attempt to read from it like a text file? *And* you write to the text file like a binary file? – Some programmer dude Oct 21 '15 at 06:16
  • 2
    Functions like `fscanf()` were not designed to work with binary files. They expect text, that should be provided in a specific standard supported by the language. – Havenard Oct 21 '15 at 06:16
  • 1
    Take a look at [**Why is “while ( !feof (file) )” always wrong?**](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong?s=1|2.6488) You need to check the return of `fscanf` (and you should probably be reading `char-by-char` from the binary file or using `fread` instead of `fscanf` -- which is for formatted text...) – David C. Rankin Oct 21 '15 at 06:16
  • I have replaced `fscanf` with the following statement: `fread((char *)&p, sizeof(p),1,fraf);` and the content from the binary file is showing in the text file however it is in binary format and not text format. – JonSnow Oct 21 '15 at 07:32
  • If you want the output file in text format you must write each of the fields of `p` to it with a text-writing function such as `fprintf(ftxt,"%d\t",p.ID)` – Weather Vane Oct 21 '15 at 07:49

1 Answers1

5

I made a number of changes to your function. The file opening mode, checking they did open, dumping the feof(), using the appropriate binary and text functions to read and write, and returning a status for whether the function operated properly.

#include <stdio.h>
#include <string.h>

struct PERSON {
    int ID;
    char name[20];
    float balance;
};

int CopyBin2Text(char* rafname, char* txtname)      // changed return value
{
    FILE *fraf, *ftxt;
    struct PERSON p;
    if ((fraf = fopen(rafname,"rb")) == NULL)
        return 0;                                   // failure

    if ((ftxt = fopen(txtname,"wt")) == NULL) {     // changed mode
        fclose(fraf);
        return 0;                                   // failure
    }
    fprintf(ftxt, "ID\tNAME\tBALANCE\n");
    fprintf(ftxt, "---------------------------------------\n");
    while(fread(&p, sizeof(p), 1, fraf) == 1)       // use return value to loop
        fprintf(ftxt, "%d\t%s\t%.2f\n", p.ID, p.name, p.balance);
    fclose(ftxt);

    fclose(fraf);
    return 1;                                       // success
}

int makefile(char* rafname)
{
    FILE *fraf, *ftxt;
    struct PERSON p = {1,"alpha", 123.45};
    struct PERSON q = {2,"beta",  100.00};
    struct PERSON r = {3,"gamma", 9.99};
    if ((fraf = fopen(rafname,"wb")) == NULL)
        return 0;                                   // failure
    fwrite(&p, sizeof(p), 1, fraf);
    fwrite(&q, sizeof(q), 1, fraf);
    fwrite(&r, sizeof(r), 1, fraf);
    fclose(fraf);
    return 1;                                       // success
}

int main(void)
{
    if (makefile("file.bin") == 0)
        printf("Failure\n");
    else {
        if (CopyBin2Text("file.bin", "file.txt") == 0)
            printf("Failure\n");
        else
            printf("Success\n");
    }
    return 0;
}

Output text file is

ID  NAME    BALANCE
---------------------------------------
1   alpha   123.45
2   beta    100.00
3   gamma   9.99
Weather Vane
  • 33,872
  • 7
  • 36
  • 56