1

我有一个文件,其中包含许多行和列的矩阵。它看起来像下面的东西:

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

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

我有两个问题:

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

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

我的部分代码如下。如果可以使用更好的方法,我可以避免使用标记化功能。

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

4 回答 4

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 中指针数学的奇迹之一。我希望这会有所帮助。

于 2013-10-01T01:01:21.187 回答
2

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

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

  1. 创建一个临时缓冲区,在其中"0x"添加到十六进制字符串(因此,如果您有字符串,则"ff"使缓冲区包含"0xff")。
  2. 将该缓冲区提供给扫描功能(sscanf适用于您的情况),并在格式字符串中提供正确的格式说明符(在这种情况下%x为十六进制)。
  3. 从变量(您提供给它的地址sscanf)中检索值,然后随意使用它。
于 2013-10-01T01:02:32.117 回答
0

您可能只是使用cinscanf读取数据作为数字,它们会自动将空格或换行符作为拆分字符,举个例子:

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

  return 0;
}

是测试。

于 2013-10-01T01:46:24.583 回答
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;
}
于 2015-07-12T11:12:24.497 回答