【问题标题】:How to get hex values from string?如何从字符串中获取十六进制值?
【发布时间】:2018-03-17 22:28:51
【问题描述】:

我有一个带有输入参数 "text" 的函数,它由一个字符串组成,该字符串包含未知数量的由空格分隔的 2 字符十六进制数字。我需要阅读它们并将它们放在单独的数组索引中,或者在 for 循环中读取它们并一一使用它们。这些值中的每一个都代表一个加密的字符(十六进制值是字符的 ascii 值)。我怎么能那样做?我想我应该使用 sscanf();但我不知道该怎么做。

char* bit_decrypt(const char* text){
    int size=strlen(text)/3;
    unsigned int hex[size];
    char*ptr;
    for(int i=0; i<size+1; i++){
        hex[i] = strtoul(text, &ptr, 16);
        printf("%x ",hex[i]);
    }
    return NULL;
}

output is: "80 80 80 80 80 80 80 80 80 80 80 80"
should be: "80 9c 95 95 96 11 bc 96 b9 95 9d 10"

【问题讨论】:

  • 你有什么代码?
  • sscanf 不会帮助你,因为你不知道数字在哪里。我会说你是靠你自己的:遍历字符串搜索0-9A-H's。或者使用正则表达式。
  • 我知道字符串的格式为:“80 9c 95 95 96 11 bc 96 b9 95 9d 10”
  • 您可以在循环中使用strtoul()base 参数为 16。它将转换一个十六进制数字,停在一个空格处,并且它会返回一个指向它转换的数字末尾的指针,这正是您需要调用strtoul on在下一次环游期间..
  • 你能帮帮我吗?我是学生,我以前从未使用过它。也许你能告诉我一些使用我上面提到的类似字符串的例子

标签: c hex


【解决方案1】:

您始终扫描text 的第一个值,因为您忘记在上一次扫描结束后立即移动strtoul 的输入。这就是 strtoul**end 参数的优点:它指向成功扫描的最后一个数字之后的字符。注意:如果没有读入,end-指针等于输入指针,这表示“格式错误的数字”或字符串的结尾。请参阅以下程序来说明这一点。希望对您有所帮助。

int main() {

    const char* input = "80 9c 95 95 96 11 bc 96 b9 95 9d 10";
    const char *current = input;
    char *end = NULL;
    while (1) {
        unsigned long val = strtoul(current, &end, 16);
        if (current == end) // invalid input or end of string reached
            break;

        printf("val: %lX\n", val);

        current = end;
    }
}

【讨论】:

    【解决方案2】:

    这也是使用strchrstrtoul(tmp,NULL,16);的可能解决方案

    在您的解决方案中,请记住 size_t arr_len = (len/3) + 1;,因为最后一个令牌只有 2 字节长。

    输入text标记被转换为字节并存储在char array中:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
      char text[] = "80 9c 95 95 96 11 bc 96 b9 95 9d 10";
    
      size_t len = strlen(text);
      size_t arr_len = (len/3) + 1;
    
      printf("len= %zu arr_len= %zu\n", len, arr_len);
      printf("Text:\n%s\n", text);
    
      char array[arr_len];
      const char *p1 = text;
    
      char tmp[3];
      tmp[2] = 0;
    
      printf("Parsing:\n");     
      for(size_t i=0; i< arr_len; i++)
      {
           p1 = strchr(p1,' ');
    
           if(p1)
           {
               tmp[0] = *(p1-2);
               tmp[1] = *(p1-1);
    
               array[i]= (char)strtoul(tmp,NULL,16);
               printf("%2x ", (unsigned char) array[i]);
    
               p1++;
    
               if(strlen(p1) == 2 ) // the last char
               {
                   i++;
    
                   tmp[0] = *(p1);
                   tmp[1] = *(p1+1);
    
                   array[i]= (char)strtoul(tmp,NULL,16);
                   printf("%2x", (unsigned char) array[i]);
               }
           }
      }
    
      printf("\nArray content:\n"); 
      for(size_t i=0; i< arr_len; i++)
      {
        printf("%2x ", (unsigned char) array[i]);  
      }
    
      return 0;
    }
    

    测试:

    len= 35 arr_len= 12
    Text:
    80 9c 95 95 96 11 bc 96 b9 95 9d 10
    Parsing:
    80 9c 95 95 96 11 bc 96 b9 95 9d 10
    Array content:
    80 9c 95 95 96 11 bc 96 b9 95 9d 10 
    

    【讨论】:

    • 它有效,但不适用于我的情况,因为我的参数是 const char。字符 *p1 = 文本;生产线出了问题
    • bmp.c:266:14: 错误:初始化从指针目标类型中丢弃“const”限定符 [-Werror=discarded-qualifiers] char *p1 = text;
    • @wannacode1881 只声明const char *p1 = text; 缓冲区text 没有被修改。
    • 是的。我只是想指出这一点。 p1 也必须是 const 。谢谢
    猜你喜欢
    • 1970-01-01
    • 2017-06-16
    • 2017-07-01
    • 2012-12-07
    • 2019-07-27
    • 2012-03-31
    • 2013-01-26
    • 2010-12-09
    • 2018-11-03
    相关资源
    最近更新 更多