我有一个包含许多行和列的矩阵的文件。看起来如下:
fa ff 00 10 00
ee ee 00 00 30
dd d1 00 aa 00
矩阵中的每个条目都是八位值的十六进制数。我想把这个文件读成二维数组。
我有两个问题:
在我的代码中使用read方法,*它包含一个包含矩阵的每个条目(两个字符)的数组。如何将每个条目传递给单个变量而不是两个字符?
当我传入单个变量时,如何将其从字符转换为十六进制? 我的意思是“ff”应该转换为0xff。
我的部分代码如下。如果可以使用更好的方法,我可以避免使用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;
}
答案 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)
转换为十六进制数字是没有意义的,因为十六进制/十进制/二进制/等只是表示在内存中以相同方式存储的值的表示。
话虽如此,将十六进制字符串转换为它所代表的数字的简单方法是:
"0x"
添加到十六进制字符串中(因此,如果您有字符串"ff"
,则缓冲区包含"0xff"
)。sscanf
将适用于您的情况)并在格式字符串中提供正确的格式说明符(在本例中为%x
表示十六进制)。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)
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;
}