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

FILE *inputFile;
FILE *outputFile;

int encodeBinary[4] = {0x00, 0x01, 0x02, 0x03};
char encodeChars[4] = {':', '@', '\n', ' '};

void encode(const char * inFile, const char * outFile)
{

    inputFile = fopen(inFile, "r");
    outputFile = fopen(outFile, "w");
    char lineBuffer[BUFSIZ];

    if(inputFile == NULL)
    {
        perror("Error while opening file.\n");
        exit(EXIT_FAILURE);
    }

    while(fgets(lineBuffer, sizeof(lineBuffer), inputFile))
    {
        for(int i = 0; lineBuffer[i] != 0; i++)
        {
            if(lineBuffer[i] == encodeChars[0])
            {
                fprintf(outputFile, "%d", encodeBinary[0]);
            }
            else if(lineBuffer[i] == encodeChars[1])
            {
                fprintf(outputFile, "%d", encodeBinary[1]);
            }
            else if(lineBuffer[i] == encodeChars[2])
            {
                fprintf(outputFile, "%d", encodeBinary[2]);
            }
            else if(lineBuffer[i] == encodeChars[3])
            {
                fprintf(outputFile, "%d", encodeBinary[3]);
            }
        }
    }

    fclose(inputFile);
    fclose(outputFile);

}

void decode(const char * inFile, const char * outFile)
{

    inputFile = fopen(inFile, "r");
    outputFile = fopen(outFile, "w");
    char lineBuffer[BUFSIZ];

    if(inputFile == NULL)
    {
        perror("Error while opening file.\n");
        exit(EXIT_FAILURE);
    }

    while(fgets(lineBuffer, sizeof(lineBuffer), inputFile))
    {
        for(int i = 0; lineBuffer[i] != 0; i++)
        {
            if(lineBuffer[i] == '0')
            {
                fprintf(outputFile, "%c", encodeChars[0]);
            }
            else if(lineBuffer[i] == '1')
            {
                fprintf(outputFile, "%c", encodeChars[1]);
            }
            else if(lineBuffer[i] == '2')
            {
                fprintf(outputFile, "%c", encodeChars[2]);
            }
            else if(lineBuffer[i] == '3')
            {
                fprintf(outputFile, "%c", encodeChars[3]);
            }
        }
    }

    fclose(inputFile);
    fclose(outputFile);

}


void commands(const char * command, const char * inputFile, const char * outputFile)
{
    if(strcmp(command, "encode") == 0)
    {
        encode(inputFile, outputFile);
    }
    else if(strcmp(command, "decode") == 0)
    {
        decode(inputFile, outputFile);
    }
}

void testValues(int argc, const char * argv[])
{
    if(argc == 4)
    {
        commands(argv[1], argv[2], argv[3]);
    }
    else
        printf("USAGE: ./encode [input_file] [output_file]\n");
}

//MAIN
int main(int argc, const char * argv[])
{

    testValues(argc, argv);

    return 0;
}

Hi there. I have this piece of code. The code is supposed to get a text file in consisting of the characters : @ "newline" and "space". These characters are then supposed to be converted to binary, 0, 1, 10, 11. After that I also need a way to decode back to the original characters. What I can't seem to figure out is how to be able to read difference between the numbers, if there is 001, how can I know that we are talking about 0, 01, and not 00, 1. I read somewhere that you can use bitwise operations to do this? Any help appreciated!

So, I have change my code a bit. Now the problem is that when I store the values the file that is encoded is as large as the file that is to be encoded. How can I store the values in a file in such a way that it stores the values as hexadecimal (or binary) so that the encoded file is smaller than the original file?

Arash Saidi
  • 2,228
  • 20
  • 36

1 Answers1

1

{0, 1, 10, 11}; are not binary numbers, they are decimal numbers, which is the default number format in C source code. The other possible number bases are hex, written with a prefix 0x and octal, written with a prefix 0. There is no way to write binary numbers in standard C code (probably because they are considered hard to read for humans).

So what you will have to do is to type the numbers in hex:

{0x00, 0x01, 0x02, 0x03}

The algorithm is pretty straight-forward:

  • Read a character from the file.
  • Search for a match of this character among encodeChars (which should be declared as const char []).
  • If found, replace it with the corresponding index in "binary".
  • Decoding is the other way around, just use the binary as lookup table instead.
  • If performance is important, consider implementing this using binary search. It is an ideal example of where binary search should be used (sorted data, no duplicates).

EDIT

What I spoke of is the representation of numbers for the programmer, inside the programmer's own source code. Here you can only use decimal, hex and octal.

There is also the representation of numbers for the user, which I suppose is what you were looking for. This can be anything you fancy.

And finally there is the representation of numbers for the CPU. He only wants binary and nothing but binary.

Consider this: printf("%c", 0x41).

  • The programmer sees hex 41.
  • The user sees the letter A.
  • The CPU sees something like "Store number 01000001 on the stack. Jump to subroutine."

To display some random byte as a binary number to the user, simply do something like:

#include <stdint.h>

uint8_t data = 0x41;

for(uint8_t i=0; i<8; i++)
{
  if( (data & (1<<i)) > 0)
  {
    printf("1");
  }
  else
  {
    printf("0");
  }

}
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thanks for the effort. But I have to represent the numbers in binary form and not octal or hex. – Arash Saidi Oct 07 '13 at 14:15
  • @HatoriSanso; Computer treat them as binary and not octal or hex! – haccks Oct 07 '13 at 14:16
  • 1
    You can use the non-standard [`0b` prefix](http://stackoverflow.com/a/2612556/249237), which works in several compilers (GCC, TCC & Clang at least) – Kninnug Oct 07 '13 at 14:17
  • @HatoriSanso You are confusing the presentation of numbers between source code <-> programmer with the presentation of numbers between program <-> user. Those are two entirely different things. Hang on, I'll edit with an example of how to print binary numbers... – Lundin Oct 07 '13 at 14:30
  • Thanks! I managed to change my code so that now each character is represented by hexadecimal number. But, the encoded file is as large as my text file? How can I store hexadecimal numbers as bits instead of characters in a text file (or any other file)? – Arash Saidi Oct 07 '13 at 14:45
  • @HatoriSanso To do that, you need to open the file as a binary one rather than a text file. Check out functions `fread` and `fwrite`. And I updated this answer with some clarifications. – Lundin Oct 07 '13 at 14:50