Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将十六进制字符缓冲区转换为ASCII字符串[C]_C_String_Hex_Printf_Ascii - Fatal编程技术网

如何将十六进制字符缓冲区转换为ASCII字符串[C]

如何将十六进制字符缓冲区转换为ASCII字符串[C],c,string,hex,printf,ascii,C,String,Hex,Printf,Ascii,我需要将十六进制字符串转换为Ascii字符串。不仅用printf显示它,还可以将它保存在内存中。 我使用此代码来显示它,但我想保存它。我该怎么办 #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;

我需要将十六进制字符串转换为Ascii字符串。不仅用
printf
显示它,还可以将它保存在内存中。 我使用此代码来显示它,但我想保存它。我该怎么办

#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];
                }
        }
}
#包括
#包括
整数十六进制到整数(字符c){
int first=c/16-3;
整数秒=c%16;
int结果=第一个*10+秒;
如果(结果>9)结果--;
返回结果;
}
int十六进制到ascii(字符c,字符d){
整数高=十六进制到整数(c)*16;
int低=十六进制到整数(d);
返回高+低;
}
int main(){
常量字符st[12]=“48656C6F3B”;
整数长度=strlen(st);
int i;
char-buf=0;
对于(i=0;i
我的第一个解决方案是使用sprintf(buf,“%c”,十六进制到ascii(buf,st[i])int for循环,但是这个解决方案不起作用,因为
sprintf
需要一个
char
的指针,正如您可能知道的那样-->…'a'=97,'b'=98…所以一旦您将十六进制转换为int,就不需要创建另一个将其转换为ascii的函数-只需将整数存储为字符即可(除非我在理解练习时遗漏了什么)

至于存储回内存:有很多选择: 1.删除
const char st[12]=“48656C6F3B”
之前的
const
,并 将函数返回值指定给所需单元格或使用sscanf


看一看

你做的每件事都很好,但也存在一些问题。请与以下内容进行比较:

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"
const char*st=“48656C6F3B”//我不想计算存储大小
charr[12]={0};//这里是我想要存储结果的
char*h=r;//指向结果中写入位置的指针
整数长度=strlen(st);
对于(int i=0;i
好的,我们来试一试:

#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;
}
要“保存”结果,只需添加一个缓冲区,
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;
}

sprintf()
当然不需要用于
%c
转换的指针。但是,如果您拥有所需的字符,只需存储它。当将“十六进制字符串”转换为“ASCII字符串”时,设计取决于此处未定义的内容:1)十六进制字符串是否总是格式正确,如果不是,结果应该是什么?2)处理A-F和A-F?3) 什么为结果字符串分配缓冲区?4) 如何处理“00”?5) 可移植到非ASCII?@chux当然可以,为什么不可以。重构毕竟是生命。好的,谢谢。
// 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[] = "0123456789ABCDEF0123456789abcdef";
  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'