前导0的基本编码不可能?

时间:2014-03-08 20:34:03

标签: c++ c

我正在尝试将字符串编码为base36。

static char *decode(unsigned long long value)
{
    char base36[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char buffer[14];
    unsigned int offset = sizeof(buffer);

    buffer[--offset] = '\0';
    do {
        buffer[--offset] = base36[value % 36];
    } while (value /= 36);

    return _strdup(&buffer[offset]);
}

int main()
{
    char original[8] = "0XDX3A1";
    unsigned long long encoded = _strtoui64(original, NULL, 36);
    char *decoded = decode(encoded);

    cout << "Original: " << original << " Decoded: " << decoded << endl;
    return 0;
}

这里的问题是,虽然这些函数工作正常:如果我尝试编码的字符串有前导0 ,则解码后的字符串比原始小一个字符(或更多)。

如何处理?

4 个答案:

答案 0 :(得分:4)

如果将字符串"01234"解码为基数为16的字符串(例如),则会得到整数值46600x1234) - 完全通过将字符串"1234""00001234"解码为base-16字符串获得的相同整数值。通过将字符串转换为整数,您可以丢弃有关前导零的任何信息。您还放弃了有关大写字母和小写字母的任何信息,假设Aa代表相同的值。

将该整数值转换回字符串不会恢复前导0,除非您明确添加它。如果你想要添加前导0(或多个0)当且仅当它们出现在原始字符串中时,你将不得不以某种方式存储该信息。

答案 1 :(得分:1)

您正在调用函数tat获取包含数值表示的字符串并将其转换为unsigned long long。两个字符串表示'00007'和'7'都转换为数字7,并且前导零丢失。

如果你想要,例如,00000036在底座36中转换为00000010,你只需要计算你想要的零,然后决定要替换它们中的多少(它取决于基数10的相对长度和基础36串?)

但转换功能似乎很糟糕。在我看来,更好的是在输出值时添加前导零。正如许多人所评论的那样,它们没有任何意义,也不应成为转换逻辑的一部分。

答案 2 :(得分:1)

  • 在您的主要内容中引入一个新变量,在zeroCount
  • 中称为main
  • 为函数decode引入第二个参数,名为zeroCount
  • original中的前导零数量计算为zeroCount中的main
  • 将零置于buffer[--offset],直到您消耗zeroCount之前的所有return

像这样:

static char *decode( unsigned long long value, int zeroCount )  
{           // introduced zeroCount argument there ^
    char base36[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char buffer[14];
    unsigned int offset = sizeof( buffer );

    buffer[--offset] = '\0';
    do {
        buffer[--offset] = base36[value % 36];
    } while ( value /= 36 );

    while ( zeroCount-- ) buffer[--offset] = '0';   // <-- added this

    return strdup( &buffer[offset] );
}

int main( )
{
    char original[8] = "0XDX3A1";
    unsigned long long encoded = _strtoui64( original, NULL, 36 );

    int zeroCount = 0;                                                  // added
    for ( int i = 0; i < sizeof original && original[i] == '0'; i++ )   // these
        zeroCount++;                                                    // three

    char *decoded = decode( encoded, zeroCount );   // <-- called along with zeroCount


    cout << "Original: " << original << " Decoded: " << decoded << endl;
    return 0;
}

由于您没有任何明显的0追加行为规则,我不得不假设您希望拥有original所具有的确切多个前导零。

答案 3 :(得分:0)

我建议你在你的方法周围创建一个包装器,然后传递一个长度参数。

例如

char * wrap_base36enc(int out_len, unsigned long long value){
    char pre_str[MAX_VAL]="", *ans = base36enc(value);
    len -= strlen(ans);

    while(len--){
     strcat(pre_str,"0");
    }
    strcat(pre_str,ans);

    return pre_str;
}