【问题标题】:Encoding and Decoding text in c在 c 中编码和解码文本
【发布时间】:2013-10-07 13:52:26
【问题描述】:
#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;
}

你好。我有这段代码。该代码应该得到一个由字符组成的文本文件:@“换行符”和“空格”。然后应该将这些字符转换为二进制,0、1、10、11。之后我还需要一种方法来解码回原始字符。我似乎无法弄清楚如何能够读取数字之间的差异,如果有 001,我怎么知道我们在谈论 0、01,而不是 00、1。我在某处读到你可以使用按位运算来做到这一点吗?任何帮助表示赞赏!

所以,我稍微更改了我的代码。现在的问题是,当我存储值时,编码的文件与要编码的文件一样大。如何将值存储在文件中,以便将值存储为十六进制(或二进制),以便编码文件小于原始文件?

【问题讨论】:

  • 字符是 7 位(不一定)不是 2 位或 3 位。
  • 是的,但我要将这些字符分别表示为 2 位。
  • 我可能应该更清楚,但是我必须将一个带有字符的文件,然后将它们编码到另一个文件为二进制,以节省空间。我该怎么做?

标签: c text encoding ascii decoding


【解决方案1】:

{0, 1, 10, 11}; 不是二进制数,它们是十进制数,这是 C 源代码中默认的数字格式。其他可能的数字基数是十六进制,前缀为0x,八进制,前缀为0。没有办法用标准 C 代码编写二进制数(可能是因为人们认为它们难以阅读)。

所以你要做的就是以十六进制输入数字:

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

算法非常简单:

  • 从文件中读取一个字符。
  • encodeChars(应声明为const char [])中搜索此字符的匹配项。
  • 如果找到,将其替换为“二进制”中的相应索引。
  • 解码是另一种方式,只需使用二进制文件作为查找表。
  • 如果性能很重要,请考虑使用二分搜索来实现。这是应该使用二分搜索的理想示例(已排序的数据,没有重复)。

编辑

我所说的是程序员在程序员自己的源代码中的数字表示。这里只能使用十进制、十六进制和八进制。

还有 user 的数字表示,我想这就是您要寻找的。这可以是你喜欢的任何东西。

最后是 CPU 的数字表示。他只想要二进制,只想要二进制。

考虑一下:printf("%c", 0x41).

  • 程序员看到十六进制 41。
  • 用户看到字母 A。
  • CPU 看到类似“在堆栈上存储编号 01000001。跳转到子程序。”

要将一些随机字节作为二进制数显示给用户,只需执行以下操作:

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

}

【讨论】:

  • 感谢您的努力。但我必须以二进制形式表示数字,而不是八进制或十六进制。
  • @HatoriSanso;计算机将它们视为二进制而不是八进制或十六进制!
  • 您可以使用非标准的0b prefix,它适用于多种编译器(至少 GCC、TCC 和 Clang)
  • @HatoriSanso 您将源代码 程序员之间的数字表示与程序 用户之间的数字表示混淆了。这是两个完全不同的东西。等等,我将编辑一个如何打印二进制数的示例...
  • 谢谢!我设法更改了我的代码,以便现在每个字符都由十六进制数字表示。但是,编码文件和我的文本文件一样大?如何将十六进制数字存储为位而不是文本文件(或任何其他文件)中的字符?
猜你喜欢
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 2012-11-20
相关资源
最近更新 更多