-1

I'm writing a program that reads a file and generates an array of integers of each byte, first I prove with a .txt file and I generates the ASCII for each of the letters and its corresping byte(for example the ASCII for B is 66, and the binary of 66 is 01000010, my program print this two in the .exe window), but I need to make the same file with the integers of the array(rest[x]), I could make a new file .txt but it has only trash, or I think is it, file.txt is the name of the new file .txt and it only has trash, I want to recover the text that is in UAM.txt, and writte in file.txt from the array rest[x];

#include<stdio.h>

int main()
{

    int b1, b2, b3, b4, b5, b6, b7, b8;
    int x, i;
    char a, b;

    FILE *f1, *bin, *fp;

    b1 = 0x01; // = 0000 0001
    b2 = 0x02; // = 0000 0010
    b3 = 0x04; // = 0000 0100
    b4 = 0x08; // = 0000 1000
    b5 = 0x10; // = 0001 0000
    b6 = 0x20; // = 0010 0000
    b7 = 0x40; // = 0100 0000
    b8 = 0x80; // = 1000 0000

    int mask[8] = { b8, b7, b6, b5, b4, b3, b2, b1 };
    int rest[8];

    f1 = fopen("UAM.txt", "rb");
    fp = fopen("file.txt", "w+");

    while (!feof(f1))
    {
        a = getc(f1);
        printf("%d\n", a);

        for (i = 0; i <= 7; i++)
        {
            rest[i] = a & mask[i];
        }

        for (i = 0; i <= 7; i++)
        {
            rest[i] = rest[i] / mask[i];
        }

        for (x = 0; x <= 7; x++)
        {
            printf("%i", rest[x]);
            fputc(rest[x], fp);
        }

        fclose(fp);

        printf("\n");
    }

    return 0;
}

the input file can be any text, for a easy example I save the word B in UAM.txt, and in the .exe window I obtained 66 and 01000010 which is the ASCII code for B in decimal and binary, next the binary number which is the byte of the word is located In an integer array(rest[x]). I need to convert this binary again to the letter B, and save this letter or any text in a new file that I named file.txt, in this file has to be again the letter B, or any text that it´s in UAM.txt sorry for my poor english!

any help will be appreciated!

  • [why-is-while-feof-file-always-wrong](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – LPs Dec 12 '16 at 07:08
  • 2
    `fclose(fp);` is inside the loop which for sure is bad. BTW - Post a short example of input file and expected output. My guess is that `fputc(rest[x], fp);` shall be `fputc(rest[x] + '0', fp);` but hat is just a guess as it is unclear to me what you really want. – Support Ukraine Dec 12 '16 at 07:08
  • `int main()` --> `int main(void)` – LPs Dec 12 '16 at 07:12
  • the input file can be any text, for a easy example I save the word B in UAM.txt, and in the .exe window I obtained 66 and 01000010 which is the ASCII code for B in decimal and binary, next the binary number which is the byte of the word is located In an integer array(rest[x]). I need to convert this binary again to the letter B, and save this letter or any text in a new file that I named file.txt, sorry for my poor english! – Juan Marcos Jimenez Dec 12 '16 at 07:15
  • Well, but how do you want to store the number into the output file? As `01000010` string? – LPs Dec 12 '16 at 07:21
  • Nope in the new file has to be the letter B again – Juan Marcos Jimenez Dec 12 '16 at 07:23

3 Answers3

0

The problem is because of use of fputc. It always prints a character, so value of rest[x] is converted into a character and then written to the file. That is why you are seeing all garbage in file.

Replace below:

fprintf(fp,"%i", rest[x]); // %i here would print the expected value
//fputc(rest[x], fp);

Also, close should be out of loop.

One more thing to notice is, as you are reading character by character till end of file, it would convert ending "\n" and "\r" characters also.

Below is the working program:

#include <stdio.h>


int main() {

int b1, b2, b3, b4, b5, b6, b7, b8;
int x, i;
char a;

FILE *f1, *fp;

b1 = 0x01; // = 0000 0001
b2 = 0x02; // = 0000 0010
b3 = 0x04; // = 0000 0100
b4 = 0x08; // = 0000 1000
b5 = 0x10; // = 0001 0000
b6 = 0x20; // = 0010 0000
b7 = 0x40; // = 0100 0000
b8 = 0x80; // = 1000 0000

int mask[8] = { b8, b7, b6, b5, b4, b3, b2, b1 };
int rest[8];

f1 = fopen("UAM.txt", "rb");
fp = fopen("file.txt", "w+");

while (!feof(f1))
{
    a = getc(f1);
    printf("%d\n", a);

    for (i = 0; i <= 7; i++)
    {
        rest[i] = a & mask[i];
    }

    for (i = 0; i <= 7; i++)
    {
        rest[i] = rest[i] / mask[i];
    }

    for (x = 0; x <= 7; x++)
    {
        printf("%i", rest[x]);
        fprintf(fp,"%i", rest[x]);
        //fputc(rest[x], fp);
    }
    fprintf(fp,"\n");
    printf("\n");
}
fclose(f1);
fclose(fp);

return 0;
}
Dipti Shiralkar
  • 362
  • 2
  • 6
0

You should reconstruct the integer starting from your array using your mask array.

#include<stdio.h>

int main(void)
{

    int b1, b2, b3, b4, b5, b6, b7, b8;
    int x, i;
    char a, b;

    FILE *f1, *bin, *fp;

    b1 = 0x01; // = 0000 0001
    b2 = 0x02; // = 0000 0010
    b3 = 0x04; // = 0000 0100
    b4 = 0x08; // = 0000 1000
    b5 = 0x10; // = 0001 0000
    b6 = 0x20; // = 0010 0000
    b7 = 0x40; // = 0100 0000
    b8 = 0x80; // = 1000 0000

    int mask[8] = { b8, b7, b6, b5, b4, b3, b2, b1 };
    int rest[8];

    f1 = fopen("UAM.txt", "rb");
    fp = fopen("file.txt", "w+");

    while ((a = fgetc(f1)) != EOF)
    {
        printf("%d\n", a);

        for (i = 0; i <= 7; i++)
        {
            rest[i] = a & mask[i];
        }

        for (i = 0; i <= 7; i++)
        {
            rest[i] = rest[i] / mask[i];
        }

        a=0;
        for (x = 0; x <= 7; x++)
        {
            printf("%i", rest[x]);
            a += rest[x] * mask[x];
        }

        printf("\n%d\n", a);

        fputc(rest[x], fp);

        printf("\n");
    }

    fclose(f1);
    fclose(fp);

    return 0;
}

A better approach could be

#include<stdio.h>

int main(void)
{

    int x, i;
    char a;

    FILE *f1, *fp;

    int rest[8];

    f1 = fopen("UAM.txt", "rb");
    if ( f1 != NULL)
    {
        fp = fopen("file.txt", "w+");

        if ( fp != NULL)
        {
            while ((a = fgetc(f1)) != EOF)
            {
                printf("%d\n", a);

                for (i = 0; i < 8; i++)
                {
                    rest[i] = a & 0x01;

                    a>>=1;
                }

                a=0;
                for (x = 7; x >= 0; x--)
                {
                    printf("%i", rest[x]);

                    a += ((0x01u << x) * rest[x]);
                }

                fputc(rest[x], fp);

                printf("\n");
            }

            fclose(fp);
        }

        fclose(f1);
    }

    return 0;
}
LPs
  • 16,045
  • 8
  • 30
  • 61
0

Problem #1:

You call fclose inside the loop which is of cause bad as you are still trying to write to the file. Move the fclose outside the while loop.

Problem #2:

while (!feof(f1))

is not the correct way to check if the end-of-file has been reached. Instead you should check the return value from getc Like:

while ((a = getc(f1)) != EOF)

Problem #3:

You can't write the binary values one by one to the output file to reproduce the original char. fputc writes a whole char - not a bit. Therefore you need to rebuild the original char from the binary values and only call fputconce.

Alternative binary calculation

Your code calculates the binary representation (bit values) correct. However, it seems that you use a too complicated method. Consider using >> (aka right shift) instead. Like:

    // Create the binary values
    for (i = 7; i >= 0; i--)
    {
      rest[i] = a & 1;
      a = a >> 1;
    }

So putting it all together, the code could be:

int main(void)
{

    int i;
    char a;
    int t;
    FILE *f1, *fp;
    int rest[8];

    f1 = fopen("UAM.txt", "rb");   // TODO: check that fopen went well
    fp = fopen("file.txt", "w+");  // TODO: check that fopen went well

    while ((a = getc(f1)) != EOF)
    {
        printf("Char representation %c\n", a);
        printf("Decimal representation %d\n", a);

        // Create the binary values
        for (i = 7; i >= 0; i--)
        {
          rest[i] = a & 1;
          a = a >> 1;
        }

        printf("Binary representation: ");
        for (i = 0; i <= 7; i++)
        {
          printf("%d", rest[i]);
        }
        printf("\n");

        // Reconstruct original value
        t = 0;
        for (i = 0; i <= 7; i++)
        {
          t = t << 1;
          t = t | rest[i];
        }

        // Write reconstructed value to file
        fputc(t, fp);
    }

    fclose(fp);
    fclose(f1);
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63