一個處理十六進制字符串轉換的最簡單方法是使用strtoul
其讀/轉換base-16
能力。 strtoul
可以和一個指針一起使用,通過輸入字符串逐步提供每個找到的值的轉換,然後將指針簡單地移動到下一個值的開頭。根據您的輸入,strchr
用於查找每個'x'
,然後轉換後面的2個字符。
爲了幫助這個過程,您可以編寫一個簡單的函數來提供轉換的所有錯誤檢查和驗證。類似以下內容的效果很好:
/** string to unsigned long with error checking */
unsigned long xstrtoul (char *p, char **ep, int base)
{
errno = 0;
unsigned long tmp = strtoul (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == ULONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtoul");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
您只需要最少的代碼即可將函數應用於數據文件中的所有行。例如:
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#include <string.h> /* for strchr */
#include <limits.h> /* for INT_MIN/INT_MAX */
#include <errno.h> /* for errno */
#define MAXL 256
unsigned long xstrtoul (char *p, char **ep, int base);
int main (int argc, char **argv)
{
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
char line[MAXL] = {0};
unsigned values[MAXL] = {0};
int base = argc > 2 ? atoi (argv[2]) : 16;
size_t i, idx = 0;
if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failen '%s'.\n", argv[1]);
return 1;
}
/* read each line in file (up to MAXL chars per-line) */
while (fgets (line, MAXL, fp)) {
char *p = line;
char *ep = p;
char digits[3] = {0};
errno = 0;
/* convert each string of digits into number */
while (errno == 0) {
/* skip any non-digit characters */
if (!(p = strchr (p, 'x'))) break;
strncpy (digits, ++p, 2);
digits[2] = 0; /* nul-terminate */
/* convert string to number */
values[idx++] = (unsigned)xstrtoul (digits, &ep, base);
if (errno || idx == MAXL) { /* check for error */
fprintf (stderr, "warning: MAXL values reached.\n");
break;
}
p += 2;
}
}
if (fp != stdin) fclose (fp);
/* print results */
for (i = 0; i < idx; i++)
printf (" values[%2zu] : 0x%02x\n", i, values[i]);
return 0;
}
/** string to unsigned long with error checking */
unsigned long xstrtoul (char *p, char **ep, int base)
{
errno = 0;
unsigned long tmp = strtoul (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == ULONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtoul");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
輸入文件
$ cat dat/hex3.txt
0x020x000x000x000x000x000x680x000x000x000x020x000x000x000x000x00
使用/輸出
$ ./bin/fgets_xstrtoul_simple dat/hex3.txt
values[ 0] : 0x02
values[ 1] : 0x00
values[ 2] : 0x00
values[ 3] : 0x00
values[ 4] : 0x00
values[ 5] : 0x00
values[ 6] : 0x68
values[ 7] : 0x00
values[ 8] : 0x00
values[ 9] : 0x00
values[10] : 0x02
values[11] : 0x00
values[12] : 0x00
values[13] : 0x00
values[14] : 0x00
values[15] : 0x00
看一下它,並讓我知道如果您有任何問題。
該文件是二進制的十六進制或字符? 'x020'不是一個十六進制字節值,那將是'x02'或'x20'。 –
licensebin的類型是什麼? – Pooya
@Pooya licensebin是無符號字符類型 –