2013-10-01 4 views
1

У меня есть файл, содержащий матрицу из многих строк и столбцов. Это выглядит как-то внизу:Преобразование строкового массива в шестнадцатеричные числа в C

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

Каждая запись в матрице представляет собой шестнадцатеричное число восьмизначного значения. Я хотел бы прочитать этот файл в двухмерном массиве.

У меня есть две проблемы:

  1. Используя метод чтения в моем коде, * он содержит массив, который имеет каждый элемент (два символа) матрицы. Как передать каждую запись в одну переменную вместо двух символов?

  2. Когда я перехожу в одну переменную, как ее преобразовать из символа в шестнадцатеричный? Я имею в виду, что «ff» следует преобразовать в 0xff.

Часть моего кода ниже. Я могу избежать функции токенизации, если лучшие методы могут быть 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; 
} 
+0

ли вы имеете в виду взять 'фа Ф.Ф. 00 10 00' как число, то мы получим' 1078020018176'? – prehistoricpenguin

+0

Нет, fa - это единственная запись. Поэтому я получу 0xfa вместо «fa». – drdot

+0

Просто см. Мое сообщение ниже. – prehistoricpenguin

ответ

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. Надеюсь, это поможет.

+0

Спасибо за ответ! Как насчет чтения каждой записи в одной переменной? – drdot

+0

Знаете ли вы заранее, сколько жетонов в строке и сколько строк? – Floris

+0

Да. Я знаю эти цифры, они передаются от stdin. – drdot

2

Преобразование в шестнадцатеричное число является бессмысленным, поскольку шестнадцатеричные/десятичные/двоичные/и т. Д. Являются просто представлениями значения, которое так же хранится в памяти.

Это, как говорится, простой способ преобразовать шестнадцатеричную строку к числу он представляет это:

  1. Создайте временный буфер, в котором вы предварять "0x" к вашей шестнадцатеричной строке (так что если у вас есть строка "ff" сделайте буфер "0xff").
  2. Дайте этот буфер функции сканирования (sscanf будет работать для вашего случая), а в строке формата укажите правильный спецификатор формата (в данном случае %x для шестнадцатеричного).
  3. Извлечь значение из переменной (адрес которой вы предоставили sscanf) и использовать ее, как вам нравится.
+0

Спасибо. Эта проблема решена. Как прочитывать каждую запись матрицы в одну переменную? – drdot

+0

Как насчет только 'tokens [0]', 'tokens [1]'? (Если вы не имеете в виду что-то еще.) –

+0

Это решает проблему. Не могли бы вы добавить несколько строк в свой ответ, и я возьму его. Но я до сих пор не понимаю, почему это [0]! = Токены [0]. – drdot

0

Вы можете просто использовать cin из scanf читать данные как цифры, они автоматически принимают пространство или новой строки, как раздвоение характер, возьмите этот пример:

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

    return 0; 
} 

Here это испытание.

0

Checkout реализации компании Apple от hexString.c

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; 
} 
Смежные вопросы