简体   繁体   English

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

[英]Convert string array into hex numbers in C

I have a file that contains a matrix of many rows and columns. 我有一个包含许多行和列的矩阵的文件。 It looks like something below: 看起来像下面的东西:

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

Each entry in the matrix is a hex number of an eight bit value. 矩阵中的每个条目都是一个八位值的十六进制数。 I would like to read this file into a two dimensional array. 我想将此文件读入二维数组。

I have two problems: 我有两个问题:

  1. Using the read method in my code, *it contains an array that has each entry (two characters) of the matrix. 使用我的代码中的read方法,*它包含一个数组,该数组具有矩阵的每个条目(两个字符)。 How can I pass each entry into a single variable instead of two characters? 如何将每个条目传递给单个变量而不是两个字符?

  2. When I pass into the single variable, how to convert it from character to hex? 当我传入单个变量时,如何将其从字符转换为十六进制? I mean "ff" should be converted to 0xff. 我的意思是“ ff”应转换为0xff。

Part of my code is below. 我的部分代码如下。 I can avoid the tokenize function if better methods can be uesd. 如果可以使用更好的方法,我可以避免使用标记化功能。

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;
}

Here is half an answer: to read a hex string and turn it into a value, you can do the following: 这是答案的一半:要读取十六进制字符串并将其转换为值,您可以执行以下操作:

#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);
}

This gets you the answer to the "how do I read two characters into one variable" part of your question, I hope. 希望您能回答问题“我如何将两个字符读入一个变量”部分。

As for the second half - if you did the following: 至于下半年-如果您执行以下操作:

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

you would see that your tokens array already contains what you are asking for: the strings. 您会看到tokens数组已经包含您要的内容:字符串。 If you convert each of them using sscanf - for example like so: 如果您使用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]);
}

You can see that this does everything you want. 您会看到这可以完成您想要的所有事情。 I used a fixed size array in the above - you clearly know how to use malloc to make a dynamically allocated array of the right size (instead of a fixed value of 10 ). 我在上面使用了固定大小的数组-您清楚地知道如何使用malloc来制作正确大小的动态分配数组(而不是固定值10 )。

One more note - the address of an array element myArray[0] can be written either as &myArray[0] , or simply as myArray . 还有一点需要注意-数组元素myArray[0]的地址可以写为&myArray[0]或简单地写为myArray For other elements, &myArray[5] is the same as myArray+5 . 对于其他元素, &myArray[5]myArray+5相同。 One of the marvels of pointer math in C. I hope this helps. C语言中指针数学的奇迹之一。我希望这会有所帮助。

Converting to a hexadecimal number is kind of meaningless, since hexadecimal/decimal/binary/etc are just representations of a value that's stored in the same way in memory anyway. 转换为十六进制数是没有意义的,因为十六进制/十进制/二进制/等只是以相同方式存储在内存中的值的表示形式。

That being said, a simple way to convert the hexadecimal string to the number it represents is this: 话虽这么说,将十六进制字符串转换为它表示的数字的一种简单方法是:

  1. Create a temporary buffer where you prepend "0x" to your hex string (so if you have the string "ff" make the buffer contain "0xff" ). 创建一个临时缓冲区,在您的十六进制字符串前添加"0x" (因此,如果您使用字符串"ff"使缓冲区包含"0xff" )。
  2. Give that buffer to a scanning function ( sscanf will work for your case) and in the format string give the correct format specifier (in this case %x for hex). 将该缓冲区分配给扫描功能( sscanf适用于您的情况),并在格式字符串中提供正确的格式说明符(在本例中为十六进制%x )。
  3. Retrieve the value from the variable (whose address you have provided to sscanf ) and use it however you like. 从变量(您提供给sscanf的地址)中检索值,并根据需要使用它。

You may just use cin of scanf to read in the data as digit, they automatically take space or newline as split character, take this example: 您可能只是使用scanf cin以数字形式读取数据,它们会自动将空格或换行符作为拆分字符,例如:

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

  return 0;
}

Here is the test. 是测试。

Checkout Apple's implementation from hexString.c 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM