在C中将字符串数组转换为十六进制数

时间:2013-10-01 00:52:46

标签: c arrays string

我有一个包含许多行和列的矩阵的文件。看起来如下:

fa ff 00 10 00
ee ee 00 00 30
dd d1 00 aa 00

矩阵中的每个条目都是八位值的十六进制数。我想把这个文件读成二维数组。

我有两个问题:

  1. 在我的代码中使用read方法,*它包含一个包含矩阵的每个条目(两个字符)的数组。如何将每个条目传递给单个变量而不是两个字符?

  2. 当我传入单个变量时,如何将其从字符转换为十六进制? 我的意思是“ff”应该转换为0xff。

  3. 我的部分代码如下。如果可以使用更好的方法,我可以避免使用tokenize函数。

    char** tokens;
    char** it;
    
    while (fgets(line, sizeof(line), file) != NULL){ /* read a line */
        tokens = tokenize(line);    // split line
    
        for(it=tokens; it && *it; ++it){
            printf("%s\n", *it);
            free(*it);
        } // end for
    } // end while
    
    char** tokenize(const char* str){
        int count = 0;
        int capacity = 10;
        char** result = malloc(capacity*sizeof(*result));
    
        const char* e=str;
    
        if (e) do {
            const char* s=e;
            e=strpbrk(s," ");
    
            if (count >= capacity)
                result = realloc(result, (capacity*=2)*sizeof(*result));
    
            result[count++] = e? strndup(s, e-s) : strdup(s);
        } while (e && *(++e));
    
        if (count >= capacity)
            result = realloc(result, (capacity+=1)*sizeof(*result));
        result[count++] = 0;
    
        return result;
    }
    

4 个答案:

答案 0 :(得分:7)

这是答案的一半:要读取十六进制字符串并将其转换为值,您可以执行以下操作:

#include <stdio.h>

int main(void) {
  char *myString="8e";
  int myVal;
  sscanf(myString, "%x", &myVal);
  printf("The value was read in: it is %0x in hex, or %d in decimal\n", myVal, myVal);
}

我希望你能得到“我如何将两个字符读入一个变量”部分问题的答案。

至于下半场 - 如果你做了以下事情:

while (fgets(line, sizeof(line), file) != NULL){ /* read a line */
    tokens = tokenize(line);    // split line

    for(int ii=0; tokens[ii]; i++) {
        printf("ii=%d; token = %s\n", ii, tokens[ii]);
    } // end for
} // end while

您会看到您的tokens数组已包含您要求的内容:字符串。如果您使用sscanf转换每个代码 - 例如:

int myValues[10];
for(int ii=0; ii<10; ii++) {
  sscanf(tokens+ii, "%x", myValues+ii);
  printf("The %dth converted value is %d - or %x in hex\n", ii, myValues[ii], myValues[ii]);
}

你可以看到这可以做你想要的一切。我在上面使用了一个固定大小的数组 - 你清楚地知道如何使用malloc来制作一个动态分配的正确大小的数组(而不是10的固定值。)

还有一点需要注意 - 数组元素myArray[0]的地址可以写为&myArray[0],也可以写为myArray。对于其他元素,&myArray[5]myArray+5相同。 C中指针数学的奇迹之一。我希望这会有所帮助。

答案 1 :(得分:2)

转换为十六进制数字是没有意义的,因为十六进制/十进制/二进制/等只是表示在内存中以相同方式存储的值的表示。

话虽如此,将十六进制字符串转换为它所代表的数字的简单方法是:

  1. 创建一个临时缓冲区,在其中将"0x"添加到十六进制字符串中(因此,如果您有字符串"ff",则缓冲区包含"0xff")。
  2. 将该缓冲区提供给扫描函数(sscanf将适用于您的情况)并在格式字符串中提供正确的格式说明符(在本例中为%x表示十六进制)。
  3. 从变量(您提供给sscanf的地址)中检索值,然后根据需要使用它。

答案 2 :(得分:0)

您可以使用cin scanf将数据作为数字读取,它们会自动将空格或换行符作为拆分字符,请举例:

int main() {
  int val;
  while (scanf("%x", &val) != EOF)
    printf("val we get : %x\n", val);

  return 0;
}

Here是测试。

答案 3 :(得分:0)

hexString.c

查看Apple的实施情况
static char byteMap[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
static int byteMapLen = sizeof(byteMap);

/* utility function to convert hex character representation to their nibble (4 bit) values */
static uint8_t
nibbleFromChar(char c)
{
    if(c >= '0' && c <= '9') return c - '0';
    if(c >= 'a' && c <= 'f') return c - 'a' + 10;
    if(c >= 'A' && c <= 'F') return c - 'A' + 10;
    return 255;
}


/* Utility function to convert nibbles (4 bit values) into a hex character representation */
static char
nibbleToChar(uint8_t nibble)
{
    if(nibble < byteMapLen) return byteMap[nibble];
    return '*';
}

/* Convert a buffer of binary values into a hex string representation */
char * bytesToHexString(uint8_t *bytes, size_t buflen)
{
    char *retval;
    int i;

    retval = malloc(buflen*2 + 1);
    for(i=0; i<buflen; i++) {
        retval[i*2] = nibbleToChar(bytes[i] >> 4);
        retval[i*2+1] = nibbleToChar(bytes[i] & 0x0f);
    }
    retval[i] = '\0';
    return retval;
}