Хорошо ... позвольте мне начать с того, что работать с необработанными системными вызовами не так просто. Вы должны принять во внимание множество проблем и крайних случаев, о которых позаботятся обычные функции stdio, даже если вы этого не заметите. Внимательно прочитайте страницу руководства для read
перед написанием программы.
С учетом вышесказанного вы можете достичь желаемого, создав простую карту, котораяотображает каждый символ ASCII в его шестнадцатеричное значение. В приведенном ниже примере я использую 0x0
, чтобы также заполнить недопустимые значения, но вы можете, например, объявить его как int8_t
и заполнить недопустимые значения -1
. Это ваше дело.
Как только у вас есть карта, которая переводит каждый символ ASCII в заданное шестнадцатеричное значение, вы можете использовать ее для простого поиска необходимых значений, например, hexmap['a'] == hexmap['A'] == 0xA
. Вы можете получить один uint8_t
, прочитав две шестнадцатеричные цифры и затем объединив их с простым сдвигом влево и двоичным ИЛИ, например:
uint8_t value = 0xA << 4 | 0x1;
// Using the map:
uint8_t value = hexmap['a'] << 4 | hexmap['1'];
// value == 0xA1
Вот рабочий пример:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
static const uint8_t hexmap[128] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
};
int main(void) {
uint8_t *buf;
int fd;
// Open file.
fd = open("your_file", O_RDONLY);
if (fd == -1) {
perror("open failed");
return 1;
}
// Allocate buffer.
// Make sure it's big enough, or reallocate while reading later.
buf = malloc(sizeof(uint8_t) * 10);
if (buf == NULL) {
perror("malloc failed");
return 1;
}
unsigned char digits[2];
size_t total = 0;
ssize_t nread;
while (1) {
nread = read(fd, digits, 2);
if (nread == -1) {
perror("read failed");
return 1;
} else if (nread == 0) {
// EOF reached
break;
}
buf[total] = hexmap[digits[0]] << 4 | hexmap[digits[1]];
total++;
// Here be sure to reallocate buf if total gets too high.
}
close(fd);
// Do whatever you want...
// For example, print the values.
for (size_t i = 0; i < total; i++) {
printf("%d: %hhu\n", i, buf[i]);
}
free(buf);
return 0;
}
Пример ввода:
0a01ff
Выход:
0: 10
1: 1
2: 255