Конвертер и компрессор между ASCII и Binary - PullRequest
0 голосов
/ 20 сентября 2010

Я пытаюсь сделать очень простой конвертер / компрессор;программа должна взять файл с 4 различными типами символов ASCII и записать его как двоичный файл в файл.Программа также должна прочитать двоичный файл, преобразовать его в ASCII и распечатать на экране.Под моим кодом, я не могу получить char / cstring.Какие улучшения нужно сделать, чтобы это заработало?

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

char compresser(char c);
char converter(char c);

int main(int argc, char **argv)
{
    char *c;
    FILE *If = fopen("A.txt", "r");
    FILE *Uf = fopen("B.txt", "rw");

    if(If == NULL || Uf == NULL) {
            printf("Could not open file");
    }

    if(argc < 4) {
        printf("Too few argument, must be 3\n");

    } else if(strcmp(argv[1], "p") == 0) {
        while((c = fgetc(If)) != EOF) {
            printf("%c", c);
        }

    } else if(strcmp(argv[1], "e") == 0) {
        while((c = fgetc(If)) != EOF) {
            fprintf(Uf, "%c\n", compresser(c));
        }

    } else if(strcmp(argv[1], "d") == 0) {
        while((c = fgetc(Uf)) != EOF) {
            printf("%c", converter(c));
        }

    } else {
        printf("Not a valid command\n");
    }
}

char compresser(char c)
{
        if(c == ' ') {
            return '00';
        } else if(c == ':') {
            return '01';
        } else if(c == '@') {
            return '10';
        } else if(c == '\n') {
            return '11';
        } else {
            return 'e';
        }
}

char converter(char c)
{
        if(c == '00') {
            return ' ';
        } else if(c == '01') {
            return ':';
        } else if(c == '10') {
            return '@';
        } else if(c == '11') {
        return '\n';
    } else {
        return 'e';
    }

}

Ответы [ 3 ]

1 голос
/ 20 сентября 2010

Ну, есть ряд проблем, которые вы, возможно, захотите решить.

Первое, что я заметил, это то, что вы проверяете наличие ошибок, печатаете сообщение об ошибке, а затем продолжаете обработку, как будто все в порядке.

Во-вторых, ваш алгоритм сжатия не алгоритм сжатия.Похоже, вы хотите, чтобы каждый несжатый символ стал двумя в сжатом виде.Даже если вы вместо этого хотите записать десятичное значение, как рекомендует Eli, вы не уменьшите пространство, необходимое для хранения символа.

Я предполагаю, что вам действительно нужно binary , не десятичное представление.Это позволит вам представлять каждый символ, используя два бита вместо полного байта.

Например, для четырех символов «A», «B», «C» и «D» одно возможное двоичное представление будет

CHAR    BITS
A   <=>   00
B   <=>   01
C   <=>   10
D   <=>   11

Затем вы можете выбрать способ объединения этих значений в сжатую форму, например, последовательность из четырех символов ABAD может быть представлена ​​как 00010011 или 11000100.Просто убедитесь, что вы разделяете их в соответствии с тем, как вы их комбинируете.

Просто чтобы прояснить, 00010011 эквивалентен десятичному числу 19.

Естьпосмотрите здесь для более подробной информации о том, как манипулировать битами.

0 голосов
/ 20 сентября 2010

Вот пример фрагмента кода:

unsigned int Compress(char letter_1, char letter_2, char letter3, char letter 4)
{
  unsigned int value = 0;
  unsigned int result = 0;
  value = letter1 - 'A';
  result = result << 2; // Shift the old to make room for new bits.
  result |= value;      // Put in new bits.
  value = letter2 - 'A';
  result = result << 2; // Shift the old to make room for new bits.
  result |= value;      // Put in new bits.
  value = letter3 - 'A';
  result = result << 2; // Shift the old to make room for new bits.
  result |= value;      // Put in new bits.
  value = letter4 - 'A';
  result = result << 2; // Shift the old to make room for new bits.
  result |= value;      // Put in new bits.
  return result;
}

Это пример сжатия буквы (letter - 'A') и упаковки в unsigned int (result = result << 2; result |= value;).

Могут быть более эффективные или компактные методы, но это только для демонстрационных целей.

0 голосов
/ 20 сентября 2010

Этот код неверен:

char compresser(char c)
{
        if(c == ' ') {
            return '00';
        } else if(c == ':') {
            return '01';
        } else if(c == '@') {
            return '10';
        } else if(c == '\n') {
            return '11';
        } else {
            return 'e';
        }
}

'00 'недопустимо в C, потому что символьный литерал должен состоять из одного символа. '\x00' означает символ со значением 0. Используйте \x00 для двоичного файла 0x00, а не 00.

Пример кода для уточнения:

#include <stdio.h>

int main()
{
    char c = '\x61';

    printf("%c\n", c);

    return 0;
}

Посмотрите, как я определил c.


Тем не менее, я не вижу, как ваш подход намеревается сжать символы.

...