0

そのため、文字のファイルを取得して、これらを2進数の文字のファイルに変換するプログラムに取り組んでいます。次に、これらの文字 (バイナリ文字) を読み取って、指定された文字に戻すことができる必要があります。

したがって、本質的にこれはファイルのエンコードとデコードです。

「@」、「/n」、「:」、「 」の 4 文字のファイルがあります。(最後はスペース)

私がこれをやりたい理由は、小さいファイルに保存したい ASCII 画像がたくさんあるからです。

unsigned char を使用して 0 に設定し、上記の文字を含むファイルを読み取り、ビットごとの演算子を使用して、読み取った値を unsigned char に割り当て、4 文字ごとに読み取ることができると言われました (それぞれ文字は 8 バイトであり、これらをそれぞれ 2 バイトに変換して 1 文字に格納できるため、1 文字に 4 文字) 各数値を文字に追加 (加算) します。

どんな助けでも大歓迎です!

私が今持っているコードはこれです:

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

FILE *inputFile;
FILE *outputFile;

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

//reads from a file and creates the encoded file
void encode(const char * inFile, const char * outFile)
{

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

    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++)
        {

            //adds four different characters to a char before adding the character to the file
            if(size < 4) {
                if(lineBuffer[i] == encodeChars[0])
                {

                }
                else if(lineBuffer[i] == encodeChars[1])
                {

                }
                else if(lineBuffer[i] == encodeChars[2])
                {

                }
                else if(lineBuffer[i] == encodeChars[3])
                {

                }

                size++;
            } else {
                size = 0;
                temp = 0;

            }
        }
    }

    fclose(inputFile);
    fclose(outputFile);

}

読み込まれたビットを一時文字に追加する方法として、誰かがいくつかの例を考え出すことができれば、本当に感謝しています。古い数字と新しい数字を表すような方法で数字を移動したり追加したりするために、数字をcharに追加する方法についてはわかりません。01が0100になるように、数値を左に3回ビットシフトできると考えています。

4

4 に答える 4

1

ビットフィールドを使用する代わりに、 << および >> 演算子とビットごとの & および | を使用できます。ビットを直接操作するには、

エンコード、

unsigned char accum;

if(size>0) accum = encodeChars[0] << 6
if(size>1) accum |= encodeChars[0] << 4
if(size>2) accum |= encodeChars[0] << 2
if(size>3) accum |= encodeChars[0]
if(lineBuffer[i] accum

デコード、

char array[4];
if(size>0) array[0] = decodeChars[ (accum >> 6) &0x3 ];
if(size>1) array[1] = decodeChars[ (accum >> 4) &0x3 ];
if(size>2) array[2] = decodeChars[ (accum >> 2) &0x3 ];
if(size>3) array[3] = decodeChars[ (accum) &0x3  ];

ビッグエンディアンとリトルエンディアンについて読んで、要素の格納順序を理解してください。

于 2013-10-07T19:37:28.090 に答える
0

他の人が言ったように、これは少し考える必要があります。あなたのキャラクターには 8 ビットがあり、4 つの 2 ビット フィールドに分割できます。したがって、最初に 8 ビット文字のすべてのビットをゼロに設定する必要があります。ファイル内の各文字は、0 ~ 3 の値にエンコードする必要があります。文字を読み取ったら、そのエンコーディングを見つけて、エンコードされた値のマスクを作成する必要があります。マスクは、8 ビット文字内の空の 2 ビット フィールドにシフトし、OR 演算する必要があります。

多くの実装固有の作業が残っていますが、それが基本的な考え方です。

于 2013-10-07T16:58:17.597 に答える
0

コードを使用して ChuckCottril の発言を確認する別の方法は、次のとおりです。

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

    FILE *inputFile;
    FILE *outputFile;

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


    //reads from a file and creates the encoded file
    void encode(const char * inFile, const char * outFile)
    {

        inputFile = fopen(inFile, "r");
        outputFile = fopen(outFile, "w");
        char lineBuffer[BUFSIZ];
        int size = 0;
        char temp = 0;
        char output_char;

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

        output_char = 0;

        while(fgets(lineBuffer, sizeof(lineBuffer), inputFile))
        {
            for(int i = 0; lineBuffer[i] != 0; i++)
            {

                //adds four different characters to a char before adding the character to the file
                if(size < 4) {
                    if(lineBuffer[i] == encodeChars[0])
                    {
                       temp = encodeBinary[0];
                    }
                    else if(lineBuffer[i] == encodeChars[1])
                    {
                       temp = encodeBinary[1];
                    }
                    else if(lineBuffer[i] == encodeChars[2])
                    {
                       temp = encodeBinary[2];
                    }
                    else if(lineBuffer[i] == encodeChars[3])
                    {
                       temp = encodeBinary[3];
                    }

                    output_char |= temp << (size*2);

                    size++;
                } else {

                    //PRINT TO FILE OUTPUT CHAR, or save to output buffer
                    size = 0;
                    temp = 0;
                    output_char = 0;

                }
            }
        }

        fclose(inputFile);
        fclose(outputFile);

    }

1 つのことに注意してください: 入力ファイルは常に 4 バイトの倍数である必要があります。そうしないと、デコードによって別のファイルが作成される可能性があります。

于 2013-10-08T07:54:45.500 に答える
0

ファイルから入力 char があるとします。これを input_char と呼びます。

unsigned char input_char;

次のように定義します。

typedef union
{
   struct
   {
      unsigned char first  :2;
      unsigned char second :2;
      unsigned char third  :2;
      unsigned char fourth :2;
   } two_bits;

   unsigned char byte;

} UNION_TWO_BITS_STORAGE;

UNION_TWO_BITS_STORAGE storage_char;

その後

storage_char.two_bits.first = (input_char & 0x03);

これは、input_char のビット 0 と 1 のみが有効な場合に有効です。それ以外の場合は、右に論理シフトする必要があります。

または、あなたが持つことができます

unsigned char temp;

switch(input_char)
{
     case '@':
        temp = 0x00;
        break;

     case '/n':
        temp = 0x01;
        break;
etc...

storage_char.two_bits.first = (temp);

そして、宛先ファイルに文字を書き戻すときは、次のように書くことができます

 storage_char.byte

はい、少し面倒ですが、よりループ可能な方法で記述できます。しかし、ここではユニオンを使用する概念を示すだけでした。

于 2013-10-07T17:10:19.273 に答える