0

因此,我正在开发一个程序,该程序将一个字符文件转换为二进制数字字符文件。然后我必须能够读取这些字符(二进制字符)并将它们转换回指定的字符。

所以本质上这是对文件进行编码和解码。

所以我有一个包含四个字符的文件:'@'、'/n'、':'、''。(最后一个是空格)

所以我想这样做的原因是我有一堆我想存储在较小文件中的 ascii 图片。

有人告诉我,我可以使用 unsigned char,将其设置为 0,然后读取包含上述字符的文件,并使用按位运算符将读取的值分配给 unsigned char,然后读取每四个字符(因为每个字符是 8 位,然后这些可以变成 2 位并存储在一个字符中,因此一个字符中有四个字符)将每个数字附加(添加)到字符。

任何帮助表示赞赏!

我现在的代码是这样的:

#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);

}

如果有人能想出一些例子来说明如何将读入的位添加到临时字符中,我将不胜感激。我不知道如何将数字添加到字符中,以便它们以这样的方式移动并以代表旧数字和新数字的方式添加。我想我可以将数字向左移动 3 次,使 01 变为 0100。

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  ];

并阅读 big-endian 与 little-endian 以了解元素存储顺序。

于 2013-10-07T19:37:28.090 回答
0

就像其他人所说的那样,这需要一点思考。您的角色有 8 位,可分为 4 个 2 位字段。因此,您最初需要将 8 位字符中的所有位设置为零。文件中的每个字符都需要编码为 0-3 之间的值。读入一个字符后,您将需要找到它的编码并创建编码值的掩码。掩码将需要移动到 8 位字符内的空 2 位字段并与它进行 OR 运算。

有很多实现特定的东西留给你做,但这是基本的想法。

于 2013-10-07T16:58:17.597 回答
0

假设你有一个来自文件的输入字符,我们称之为 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 回答
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);

    }

请注意一件事:您应该始终拥有 4 字节的倍数的输入文件,否则解码可能会导致不同的文件!

于 2013-10-08T07:54:45.500 回答