2016-04-06 638 views
2

我需要将十六进制字符串转换为Ascii字符串。不仅可以用printf显示,还可以将其保存在内存中。 我使用此代码来显示它,但我想保存它。我该怎么办?:如何将十六进制字符缓冲区转换为ASCII字符串[C]

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

int hex_to_int(char c){ 
     int first = c/16 - 3; 
     int second = c % 16; 
     int result = first*10 + second; 
     if(result > 9) result--; 
     return result; 
} 

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

int main(){ 
     const char st[12] = "48656C6C6F3B"; 
     int length = strlen(st); 
     int i; 
     char buf = 0; 
     for(i = 0; i < length; i++){ 
       if(i % 2 != 0){ 
         printf("%c", hex_to_ascii(buf, st[i])); 
       }else{ 
         buf = st[i]; 
       } 
     } 
} 

我的第一个解决方案是使用sprintf(buf,"%c",hex_to_ascii(buf,st[i]) INT for循环,但这种方法行不通,因为sprintf需要的char的指针。

+2

'的sprintf()'当然并不需要一个指针用于'%C'转换。但是,如果您拥有所需的角色,只需存储它即可。 – unwind

+0

将“Hex string”转换为“ASCII string”时,设计取决于未在此处定义的内容:1)十六进制字符串是否始终保持格式良好,如果不是,结果应如何? 2)处理A-F和a-f? 3)为结果字符串分配什么缓冲区? 4)如何处理“00”? 5)可移植到非ASCII? – chux

回答

2

好吧,让我们有一个镜头:

#include <ctype.h> 
#include <stdio.h> 

static unsigned char hexdigit2int(unsigned char xd) 
{ 
    if (xd <= '9') 
    return xd - '0'; 
    xd = tolower(xd); 
    if (xd == 'a') 
    return 10; 
    if (xd == 'b') 
    return 11; 
    if (xd == 'c') 
    return 12; 
    if (xd == 'd') 
    return 13; 
    if (xd == 'e') 
    return 14; 
    if (xd == 'f') 
    return 15; 
    return 0; 
} 

int main(void) 
{ 
    const char st[] = "48656C6C6F3B", *src = st; 
    char text[sizeof st + 1], *dst = text; 

    while (*src != '\0') 
    { 
    const unsigned char high = hexdigit2int(*src++); 
    const unsigned char low = hexdigit2int(*src++); 
    *dst++ = (high << 4) | low; 
    } 
    *dst = '\0'; 
    printf("Converted '%s', got '%s'\n", st, text); 
    return 0; 
} 

的非常详细的前瞻性digit2int()功能是试图不ASCII依赖,这总是好的。请注意,main()中的循环假设输入正确,它仅检查每两个字符的终止并且不处理非十六进制数据。

哦,这个打印:

Converted '48656C6C6F3B', got 'Hello;' 
+0

@chux当然,为什么不。毕竟,重构就是生活。完成,谢谢。 – unwind

0

你可能知道每个character is represented by an int - > ...'a'= 97,'b'= 98 ...因此,一旦你将一个十六进制转换为int,就不需要创建另一个函数,将它转换为ascii - 只要将整数存储到一个字符中就可以做到这一点(除非我错过理解练习的东西)。

作为用于存储回存储器:有很多种选择: 1.除去constconst char st[12] = "48656C6C6F3B";和 之前,从函数的返回值分配给期望的细胞或使用的sscanf

看一看here

0

你做得很好,但有一些问题。有以下比较:

const char* st = "48656C6C6F3B"; // I don't want to calculate storage size 
char r[12] = { 0 }; // Here is I want to store the result 
char* h = r; // pointer to write position in the result 
int length = strlen(st); 
for (int i = 0; i < length; i+=2) { 
    assert((h - r) < sizeof(r)); // check that there is not problem with out of range 
    *h++ = hex_to_ascii(st[i], st[i + 1]); 
} 
printf("%s", r); // now the r contains "ansi string" 
0

“拯救” 的结果,简单的增加一个缓冲区,dest,存储结果。

代码中包含的其他建议。

// add void to signature 
int main(void) { 
    const char st[12] = "48656C6C6F3B"; 
    int length = strlen(st); 
    int i; 
    char buf = 0; 

    // add destination buffer 
    char dest[10]; 

    // Add test 
    // for (i = 0; i < length; i++) { 
    for (i = 0; i < length && (i/2 + 1) < sizeof(dest); i++) { 
    if (i % 2 != 0) { 

     // printf("%c", hex_to_ascii(buf, st[i])); 
     dest[i/2] = hex_to_ascii(buf, st[i]); 

    } else { 
     buf = st[i]; 
    } 
    } 

    // Add termination 
    dest[i/2] = '\0'; 
    // Do someting with dest 
    puts(dest); 
    return 0; 
} 

可替换地,一些代码,处理各种可能的问题:下/上壳体十六进制数字,无效字符,奇数,小缓冲器,嵌入空字符。

#include <stdlib.h> 
#include <string.h> 
// There are _many_ ways to do this step. 
unsigned char2digit(int ch) { 
    static const char Hex[] = "ABCDEFabcdef"; 
    char *p = memchr(Hex, ch, 32); 
    if (p) { 
    return (unsigned) (p - Hex) % 16; 
    } 
    return (unsigned) -1; // error value 
} 

// Return NULL with ill-formed string 
char *HexStringToString(char *dest, size_t size, const char *src) { 
    char *p = dest; 
    if (size <= 0) { 
    return NULL; 
    } 
    size--; 
    while (*src) { 
    if (size == 0) return NULL; 
    size--; 

    unsigned msb = char2digit(*src++); 
    if (msb > 15) return NULL; 
    unsigned lsb = char2digit(*src++); 
    if (lsb > 15) return NULL; 
    char ch = (char) (msb * 16 + lsb); 

    // Optionally test for embedded null character 
    if (ch == 0) return NULL; 

    *p++ = ch; 
    } 
    *p = '\0'; 
    return dest; 
} 

void testHex(const char *s) { 
    char buf[10]; 
    char *dest = HexStringToString(buf, sizeof buf, s); 
    printf("%-24s --> '%s'\n", s, dest ? dest : "NULL"); 
} 

#include <stdio.h> 
int main(void) { 
    testHex("48656C6C6F3B");  // upper case 
    testHex("48656c6c6f3b");  // lower case 
    testHex(""); 
    testHex("48656C6C6F3B48656C"); 
    // fails 
    testHex("48656C6C6F3B48656C6C"); // Too long 
    testHex("48656C6C6F3B0");  // Odd character count 
    testHex("48656C6C6F3Bxx");  // Non-hex character 
    testHex("48006C6C6F3B");   // null character 
    return 0; 
}   

输出

48656C6C6F3B    --> 'Hello;' 
48656c6c6f3b    --> 'Hello;' 
         --> '' 
48656C6C6F3B48656C  --> 'Hello;Hel' 
48656C6C6F3B48656C6C  --> 'NULL' 
48656C6C6F3B0   --> 'NULL' 
48656C6C6F3Bxx   --> 'NULL' 
48006C6C6F3B    --> 'NULL' 
相关问题