2017-07-24 92 views
-3

以十六进制字符串形式输入一个输入,然后将其转换为C中的字符串。十六进制字符串可以包含0x00,在转换时转换为Ascii中的0。这终止了字符串。我必须将值存储在char字符串中,因为API使用它。
我迄今为止代码:如何将字符串中的ascii值存储为0而不终止它?

int hex_to_int(unsigned char c) { 
    int first =0; 
    int second =0; 
    int result=0; 
    if(c>=97 && c<=102) 
     c-=32; 
    first=c/16 - 3; 
    second =c % 16; 
    result = first*10 + second; 
    if(result > 9) result--; 
     return result; 
} 
unsigned char hex_to_ascii(unsigned char c, unsigned char d){ 
    unsigned char a='0'; 
    int high = hex_to_int(c) * 16; 
    int low = hex_to_int(d); 
    a= high+low; 
    return a; 
} 
unsigned char* HextoString(unsigned char *st){ 
    int length = strlen((const char*)st); 
    unsigned char* result=(unsigned char*)malloc(length/2+1); 
    unsigned char arr[500]; 
    int i; 
    unsigned char buf = 0; 
    int j=0; 
    for(i = 0; i < length; i++) 
    { 
     if(i % 2 != 0) 
    { 
     arr[j++]=(unsigned char)hex_to_ascii(buf, st[i]); 
    } 
    else 
    { 
     buf = st[i]; 
    } 
    } 
    arr[length/2+1]='\0'; 
    memcpy(result,arr,length/2+1); 
    return result; 
} 
+6

没有什么能阻止你把一个空字节的字符串,但需要一个字符串的函数(strlen的(),printf()函数等)会认为这是一个结束标记。 –

+0

值得检查api文档,了解它如何期望这些十六进制字符串被转换。 – Orangesandlemons

+3

你不是在混合'NUL'字符(ASCII值= 0)和“0”字符(ASCII值= 48)吗?显示你的代码。没有代码,问题就不清楚了。 –

回答

6

可以存储在字符数组的任何值。但是如果你想存储一个0x00的值,你不能在这个数组上使用字符串函数。所以你必须使用一个整数变量来存储你想存储的数据的长度。然后你可以编写使用这个整数的函数。

+0

如果我从函数返回字符串,它会切断字符串,因为空字符。在那种情况下做什么? –

+2

@dennismenice:没有任何东西会被切割,它只是一个字符数组,只要你没有使用不会发生的C字符串函数...显示一些代码,以便明确你的意思。 –

+0

@dennismenice:这仅仅是'cut',因为期望字符串作为输入的函数会忽略NUL字符后面的所有内容。当你返回值时,你返回一个指向内存的指针。当函数返回时,什么都不会被“切断”。 – cdo256

0

如您现在提供了更多信息,我可以告诉您,您的函数不会削减任何内容,因为它会循环显示您提供的整个C字符串,例如输入为"0a12345600a0020b12"。这个“问题”是,如果你想在转换后得到输出字符串的长度(strlen()),例如它会在处停止,并且就原始输入字符串而言,你会得到一个“错误的”长度。

它非常像它写在answer of Xaver保存的长度信息和字符串,使用该长度,而不是通过C字符串函数,如strlen()

要说明的是,为了提供一个合适的长度信息,我添加了一个struct定义代码定义由size_t len的字符串类型和unsigned char* str称为HexString。有了额外的长度信息,你可以处理一个0字节。此外,我对代码做了一些修改,例如您不需要堆栈上的字符缓冲区arr

有了您的输入:"0a12345600a0020b12"
以下输出,你会看到:<0a> <12> <34> <56> <00> <a0> <02> <0b> <12> <00>
如果打印C-十六进制字符串每一个字符。最后的<00>是空终止。

here on ideone为一个现场的例子。

代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct 
{ 
    size_t   len; /* C-string length + '\0' */ 
    unsigned char* str; 
} HexString; 

int hex_to_int(unsigned char c) 
{ 
    int first =0; 
    int second =0; 
    int result=0; 
    if (c >= 97 && c <= 102) /* 97 = 'a'; 102 = 'f' */ 
     c -= 32; 
    first = c/16 - 3; 
    second = c % 16; 
    result = first * 10 + second; 
    if (result > 9) result--; 
    return result; 
} 

unsigned char hex_to_ascii(unsigned char c, unsigned char d) 
{ 
    unsigned char a = '0'; 
    int high = hex_to_int(c) * 16; 
    int low = hex_to_int(d); 
    a = high + low; 
    return a; 
} 

HexString HextoString(const char* const st) 
{ 
    HexString result; 
    size_t length = strlen(st); 
    result.len = length/2+1; 
    result.str = malloc(length/2+1); 
    size_t i; 
    size_t j = 0; 
    unsigned char buf = 0; 
    for (i = 0; i < length; i++) 
    { 
     if (i % 2 != 0) 
     { 
     result.str[j++] = hex_to_ascii(buf, st[i]); 
     } 
     else 
     { 
     buf = (unsigned char)st[i]; 
     } 
    } 
    result.str[length/2+1] = '\0'; 
    return result; 
} 

int main() 
{ 
    size_t i; 
    HexString hexString = HextoString("0a12345600a0020b12"); 
    for (i = 0; i < hexString.len; ++i) 
    { 
     printf("<%02x> ", hexString.str[i]); 
    } 

    free(hexString.str); 

    return 0; 
} 
+0

Hi @ dennismenice如果此问题或任何答案已解决您的问题,请考虑[接受它](https://meta.stackexchange.com/q/5234/ 179419)通过点击复选标记。这向更广泛的社区表明,您已经找到了解决方案,并为答复者和您自己提供了一些声誉。没有义务这样做。 –

相关问题