Search code examples
cfilebinaryfiles

convert to binary file


I need to convert a text file of the following format to binary file. The input file only contains characters A, B, C or D. 'A' changes to '00','B' changes to '01', C changes to '10', D changes to '11'. Sample input file:

ABBCDA
BBAABCD
BACBB

Sample output file:

000101101100
01010000011011
0100100101

I have wrote the following code, but it doesn't work.

int main()
{
    FILE * fop;
    FILE * fout;
    int length=0;
    int i;
    char buffer[1000];
    fop = fopen("filename.txt","r");
    fout = fopen("filename.bin", "wb");
    while(!feof(fop))
    {
        fgets(buffer,1000,fop);
        length = strlen(buffer)-1;
        for(i=0; i<length; i++)
         {
           if(buffer[i]=='A')
           strcpy(buffer[i],'00');
           if(buffer[i]=='B')
           strcpy(buffer[i],'01');
           if(buffer[i]=='C')
           strcpy(buffer[i],'10');
           if(buffer[i]=='D')
           strcpy(buffer[i],'11'); 
         }
      fwrite(buffer, 1, sizeof(char)*length, fout);
      fwrite("\n",1,sizeof(char),fout);
    }
    fclose(fop);
    fclose(fout);
    return 0;
}

What's wrong? How to solve it? Thank you.


Solution

  • This is the part to be fixed

    while(fgets(buffer,1000,fop))
    {
        length = strlen(buffer)-1;
        char sout[3];
        for(i=0; i<length; i++)
        {
            *sout = '\0';
            if(buffer[i]=='A')
                strcpy(sout,"00");
            if(buffer[i]=='B')
                strcpy(sout,"01");
            if(buffer[i]=='C')
                strcpy(sout,"10");
            if(buffer[i]=='D')
                strcpy(sout,"11"); 
            fwrite(sout, 1, strlen(sout), fout);
        }
        fwrite("\n",1,sizeof(char),fout);
    }
    

    Notes

    • the fgets within the while condition
    • sout to store temporarily the 2-bits (as string)
    • fwrite writes to sout (does not overwrite buffer), and is integrated within the for loop while the writing of \n is outside.

    Version to write actual bytes (in binary) ...

    while(fgets(buffer,1000,fop))
    {
        length = strlen(buffer)-1;
        for(i=0; i<length; i++)
        {
            unsigned char byte = 0;
            if(buffer[i]=='A')
                byte = 0x0;
            if(buffer[i]=='B')
                byte = 0x1;
            if(buffer[i]=='C')
                byte = 0x2;
            if(buffer[i]=='D')
                byte = 0x3; 
            fwrite(&byte, 1, 1, fout);
        }
        // no more : fwrite("\n",1,sizeof(char),fout);
    }
    

    Using 0x notation to show I'm dealing with binary stuff...

    And version David C. Rankin (perfectionist!)

    while (fgets (buf, MAXC, fop)) {    /* read each line */
        char *p = buf;                  /* pointer to buf */
        while (*p) {                    /* while not '\0' */
            uint8_t byte = 0;           /* declare byte */
            if ('A' <= *p && *p <= 'Z') /* if char is A-Z */
                byte = *p - 'A';        /* encode 0 - 25 */
            else
                byte = *p;              /* write char as is */
            if (fwrite (&byte, 1, 1, fout) != 1) {   /* validate write */
                fprintf (stderr, "error: write of '%c' failed.\n", *p);
                goto badwrite;          /* jump out of loops on fail */
            }
            p++;    /* increment pointer */
        }
    }
    badwrite:;
    
    fclose (fop);                /* close input file */
    if (fclose (fout) == -1)     /* close/validate output file */
        fprintf (stderr, "error: on fout close.\n");
    

    There is yet some stuff that can be improved, but for now ...