-1

非常に簡単なコンバーター/コンプレッサーを作ろうとしています。プログラムは、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';
    }

}

4

3 に答える 3

1

さて、対処したい問題がいくつかあります。

私が最初に気付いたのは、エラー条件をテストし、エラー メッセージを出力してから、すべてが正常であるかのように処理を続行していることです。

2 つ目は、圧縮アルゴリズムが圧縮アルゴリズムではないことです。現状では、圧縮されていない各文字を 2 つの圧縮形式にしたいようです。Eli が提案するように 10 進値を代わりに書きたい場合でも、文字を格納するために必要なスペースを削減していません。

私の推測では、あなたが本当に欲しいのはバイナリであり、10 進表現ではありません。これにより、1 バイトではなく 2 ビットを使用して各文字を表すことができます。

たとえば、「A」、「B」、「C」、および「D」の 4 文字が与えられた場合、1 つの可能なバイナリ表現は次のようになります。

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

次に、これらの値を圧縮形式に結合する方法を選択できます。たとえば、4 つの文字シーケンス ABAD は00010011またはとして表すことができます11000100。それらを組み合わせる方法に対応する方法でそれらを分離することを確認してください.

明確00010011にするために、 は decimal と同等19です。

ビットの操作方法の詳細については、こちらをご覧ください。

于 2010-09-20T17:37:59.813 に答える
0

以下は、コード フラグメントの例です。

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 intresult = result << 2; result |= value;

もっと効率的またはコンパクトな方法があるかもしれませんが、これはデモンストレーションのみを目的としています。

于 2010-09-20T18:24:39.747 に答える
0

このコードは正しくありません:

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';
        }
}

文字リテラルは 1 文字で構成される必要があるため、'00' は C では無効です。'\x00'は、値が 0 の文字を意味します。ではなく\x00、バイナリに使用します。0x0000

明確化のためのコード例:

#include <stdio.h>

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

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

    return 0;
}

を定義した方法を参照してくださいc


とはいえ、あなたのアプローチがどのように文字を圧縮しようとしているのかわかりません。

于 2010-09-20T17:24:45.850 に答える