【问题标题】:Converter and compresser between ASCII and BinaryASCII 和二进制之间的转换器和压缩器
【发布时间】:2011-04-14 19:21:35
【问题描述】:

我正在尝试制作一个非常简单的转换器/压缩器;该程序应该获取一个包含 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';
    }

}

【问题讨论】:

  • 你的问题很模糊!你怎么了?我怀疑 compresser() 编译!如果您尝试压缩,则必须使用字节 00000000、00000001、00000010、00000011 作为映射。这就是我能建议的全部。
  • "rw" 不是fopen 的有效参数。

标签: c binary char ascii cstring


【解决方案1】:

您可能想解决许多问题。

我注意到的第一件事是您测试错误条件,打印错误消息,然后继续处理,好像一切正​​常。

第二个是您的压缩算法不是压缩算法。就目前而言,您似乎希望每个未压缩的字符以压缩形式变为两个。即使您希望按照 Eli 的建议写入十进制值,也不会减少存储字符所需的空间。

我猜你真正想要的是binary,而不是十进制表示。这将允许您使用两位而不是完整字节来表示每个字符。

例如,给定四个字符“A”、“B”、“C”和“D”,一种可能的二进制表示是

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

然后您可以选择如何将这些值组合成压缩形式,例如四个字符序列 ABAD 可以表示为0001001111000100。只需确保您将它们分开的方式与您组合它们的方式相对应。

只是为了说清楚00010011等于十进制19

查看here 了解有关如何操作位的更多详细信息。

【讨论】:

  • 谢谢。这是我需要快速完成的事情,有人可以给我一个开始吗?
  • @user265767:使用查找表或数组。或者你可以用算术方法做到这一点:compression_code = letter - 'A';。接下来,使用位移位和二进制或来打包位。
  • @user265767:查看我发布的答案。
【解决方案2】:

此代码不正确:

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的。


不过,我不明白您的方法打算如何压缩字符。

【讨论】:

  • 我要做的是读取一个字符并获取二进制值。但是我需要知道 ' ' - (blank) = 的二进制值? : = ? @=? \n = ?你能给我这个的二进制值吗?
  • @user265767:我想你很困惑。字符的二进制值 存储在文件中。事实上,计算机现在除了二进制值之外不能存储太多东西。对字符及其在计算机中的表示进行一些背景阅读,并阅读 ASCII。对于“...的二进制值”字符,谷歌“ascii table”
【解决方案3】:

这是一个示例代码片段:

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 &lt;&lt; 2; result |= value;) 的示例。

可能有更有效或更紧凑的方法,但这仅用于演示目的。

【讨论】:

    猜你喜欢
    • 2020-10-17
    • 2011-01-22
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多