将读取char与读取整数区分开来

时间:2015-05-20 03:40:22

标签: c char

我在C中实现RLE算法,我遇到了一个很大的问题。我使用@作为压缩/解压缩的标识符。让我用例子说明:

0 0 0 0 1 2 0 0 0 0 = @ 0 4 1 2 @ 0 4

@ X Y =重复X,Y次。数字从0到255(unsigned char)不等。但是,数字64让我感到困惑,因为它与'@'相同。

程序读取64 0 5

我希望:64 0 5(不需要减压)

得到的结果:0 0 0 0 0(64存储在char变量中,然后程序将其用作'@')

if (var == '@') {
    // decompress
}

5 个答案:

答案 0 :(得分:1)

您需要选择一个绝对不会用作转义机制的字符序列。如果您将输入转换为@ <character> <count>,如果同一个字符连续出现至少3次,那么您未转换的最差输入将有2个连续的@字符。

输入中另一个最坏的情况是有64个@字符,产生@ @ @。所以,我们确定输出不能连续超过3个。

鉴于此,你可以将单个@字符表示为@@@@,它产生4个字符。如上所示,RLE的输出不能有4个连续的@(或任何其他4个连续的字符,以这种方式)

但相反,如果你总是将@转换为@ @ <count>,你可以保留一个字节,你只需要修改项目的RLE创建部分,因为这种格式是完美的根据RLE解析器很好。

答案 1 :(得分:1)

我猜你正在使用一些scanf - 类似函数来解析你的输入。

别。在这种情况下它不起作用。

相反,只需读取输入字符串,将空格拆分为标记(示例:"@ 0 4 1 2 @ 0 4" - &gt; "@", "0", "4", "1", "2", "@", "0", "4""64 0 5" - &gt; "64", "0", "5"

下一步是解析。在那里你可以淘汰@ - s。你可以很容易地将它们与64 - strlen("@") == 1strlen("64") == 2区分开来,你知道了吗?)

当您遇到纯数字字符串时,您可以使用atoi之类的内容将其转换为整数(之后您可以将其转换为unsigned char)。

答案 2 :(得分:0)

这可能不是解决问题的最佳方法,但它可以胜任。 c编译器会根据需要自动将int转换为char,将char转换为int。如果您可以找到限制此行为的方法,则问题将得到解决。我通过将字符转换为respective ASCII并将其与ASCII value的{​​{1}}进行比较来限制行为。

该程序的一个明显问题是它读取单个字符,并且它永远不会出现64个整体,但即使我们修改程序以将空格分隔为分隔符,我也不认为这样做有任何问题

@

答案 3 :(得分:0)

转义重复指令的一个非常简单的解决方案是重复字符。

让我解释一下:

0 0 0 0编码为0 0 2(2表示重复前一个字符的2倍)

小心重复2次:

3 4 4 5应编码为3 4 4 0 5

0意味着不再有'4'。

解码时只需查找重复的字符,找到后,将下一个字符作为重复字符的次数。

未经测试的例子:

int input_char(void);
void output_char(int);

void encode(void) {
    int c, previous_c = EOF;
    int repeating = 0, repetitions;

    while ((c = input_char()) != EOF) {
        if (repeating) {
            if (c == previous_c && repetitions < 255) {
                ++repetitions;
            } else {
                output_char(repetitions);
                output_char(c);
                repeating = 0;
            }
        } else {
            output_char(c);
            if (previous_c == c) {
                repeating = 1;
                repetitions = 0;
            }
        }
        previous_c = c;            
    }
}

void decode(void)
{
    int c, previous_c = EOF;

    while ((c = input_char()) != EOF) {
        output_char(c);
        if (c == previous_c) {
            int repetitions = (unsigned char) input_char();

            while (repetitions--) {
                output_char(c);
            }
        }
        previous_c = c;            
    }
}

答案 4 :(得分:0)

查看此ascii table:您可以看到数字的范围,用它来确定您是否正在阅读数字:

if (var >= 48 && var <= 57) {/* I'm an integer */}