0

I'm making a program that writes a binary file, the content of this binary file are in an unsigned char pointer. The next code is the way that I using to generate the binary

while (f > 0) {
    oct = (unsigned char) *datosOct->informacion++;

    for (int i = 2; i >= 0; --i)
    {   
        char actual = ((oct & (1 << i)) ? '1' : '0');
        temporal = appendCharToCharArray(temporal, actual);
    }           
    f--;
}
datosBin->informacion = (unsigned char*)temporal;

I had used fopen in mode wb, but it literals write a file with 1s and 0s. this is the function that I use to write (I using the default compiler of Visual Studio). I use the next code to write the file

file = fopen(nombreArchivo, "wb");
fwrite(datosBin->informacion, sizeof(char), archivoEnOctal->tamanio, file);

My starting point is a char array that contains '1's and '0's, each byte of '1's and '0's represents an ASCII value. For example, '1010000' is the ASCII 80 representing the letter 'P', if I transforms the binary char array ('1010000') to an array of chars ('P') when it finds values whose ASCII is 00 takes them as the end of the text and does not write them to the final file. One of the possible outputs of my code is an image, so I need to write these values 00. I tried this to write the chars directly, but this doesn't work for the images for the reason I mentioned before

while (f > 0) {
    oct = (unsigned char) *datosOct->informacion++;

    for (int i = 2; i >= 0; --i)
    {   
        if (size == 8) {
            size = 0;
            char nuevaLetra = strtol(temporal, 0, 2); 
            if (nuevaLetra == 00) {
                nuevaLetra = '\0';
                //nuevaLetra = (char) 0;
            }
            response = appendCharToCharArray(response, nuevaLetra);
            temporal = (char*)"";
        }
        size++;
        char actual = ((oct & (1 << i)) ? 1 : 0);
        temporal = appendCharToCharArray(temporal, actual);
    }           
    f--;
}
12
  • 2
    What's your question? Commented Apr 27, 2020 at 0:11
  • 1
    Writing only binary, or not even binary? char actual = ((oct & (1 << i)) ? '1' : '0'); assigns the character '0' or '1' not the value 0 or 1. Commented Apr 27, 2020 at 0:15
  • 1
    Just write the byte. Commented Apr 27, 2020 at 0:17
  • 1
    @juanjosemontoya - The code char actual = ((oct & (1 << i)) ? 1 : 0); is not the same as char actual = ((oct & (1 << i)) ? '1' : '0'); - your last comment is untrue. Commented Apr 27, 2020 at 0:29
  • 1
    @enhzflep when I use the char actual = ((oct & (1 << i)) ? '1' : '0'); my outup is a file with character '0' or '1' , but when I use char actual = ((oct & (1 << i)) ? 1 : 0); I get a file whit the ascii values of 0 and 1, twice ways are not my expecter output. Commented Apr 27, 2020 at 0:36

1 Answer 1

3

I'll leave it to you to build and run it, before looking inside output.txt

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    unsigned char data;
    unsigned char numBitsValid;
} bitAccumalator_t;

int main()
{
    FILE *fp = fopen("output.txt", "wb");
    char *inputStream = "011001000110111101100101011100110010000001110100011010000110100101110011001000000110100001100101011011000111000000111111";
    int numBits = strlen(inputStream);
    bitAccumalator_t outBuffer = {0,0};
    for (int i=0; i<numBits; i++)
    {
        outBuffer.data <<= 1;
        if (inputStream[i] == '1')
        {
            outBuffer.data |= 1;
        }
        outBuffer.numBitsValid++;

        if (outBuffer.numBitsValid == 8)
        {
            fwrite(&outBuffer.data, 1, 1, fp);
            outBuffer.data = 0;
            outBuffer.numBitsValid = 0;
        }
    }
    fclose(fp);
    return 0;
}
Sign up to request clarification or add additional context in comments.

6 Comments

Wow impressive, could you please explain us a little bit how you code works? I'm newbie in C
@JohnGuzman - try stepping through the code with a debugger. It puts either 1 or 0 into the least significant bit of an accumalator until it has filled the byte. Once done, it writes that byte to the output. <<= and |= are bitwise operators. 00000001b << 1 = 00000010b. Next, 00000010b | 1 = 00000011b. As the output.txt asks, does this help?
Yes! Thanks. Now my question is, this should works as well if we save those chars to an array and then writing them all to the file instead of writing to the file one by one?
@JohnGuzman - yes, absolutely. That's the preferred method - I just wanted to provide an easy to digest answer.
regarding: outBuffer.data |= 1; This is always going to set the same bit. Probably not what you want. Suggest inserting, before that statement: outBuffer.data <<= 1;
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.