我正在尝试将字符串编码为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 ,则解码后的字符串比原始小一个字符(或更多)。
如何处理?
答案 0 :(得分:4)
如果将字符串"01234"
解码为基数为16的字符串(例如),则会得到整数值4660
(0x1234
) - 完全通过将字符串"1234"
或"00001234"
解码为base-16字符串获得的相同整数值。通过将字符串转换为整数,您可以丢弃有关前导零的任何信息。您还放弃了有关大写字母和小写字母的任何信息,假设A
和a
代表相同的值。
将该整数值转换回字符串不会恢复前导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;
}