2009-10-16 2 views
1

В настоящее время я пытаюсь читать значения Hex из текстового файла.Чтение в шестнадцатеричных значениях (C)

Там может быть несколько строк Hex-х и каждая строка может быть столько, сколько необходимо:

f53d6d0568c7c7ce 

    1307a7a1c84058 

    b41af04b24f3eb83ce 

В настоящее время я поставил вместе простой цикл для чтения в значениях Hex в unsigned char line[500] с fscanf как таковой:

for(i=0; i < 500; i++) 
    { 
     if (fscanf(fp, "%02x", &line[i]) != 1) break; 
    } 

В настоящий момент это только чтение в первой строке. Кроме того, это определенно не лучший подход, чтобы просто бросить случайный 500, который нужно прочитать.

Я предполагал, что могу использовать sscanf с fgets или что-то в этом роде. Но я не знал, будет ли это лучший подход.

Если бы кто-нибудь мог помочь мне указать мне в правильном направлении, я был бы очень признателен.

ответ

3

Вы на правильном пути с fgets() и sscanf(); что позволит вам правильно подобрать размер. Если ваши данные действительно в этом формате, sscanf() может быть излишним; вы можете просто написать цикл быстрого преобразования и сохранить все эти вызовы с переменной скоростью.

+1

Просто помните, 'ToUpper()' и 'TOLOWER()' в 'ctype.h' заголовок, прежде чем мы катимся наши собственные шестигранный конвертер. Поддержка нечувствительных к регистру данных никогда не бывает плохой. –

+0

@ Крис, абсолютно; хороший звонок. –

3

Обратите внимание, что sscanf работает медленно (вызовы библиотеки, использование памяти и избыток). Кроме того, это слишком опасно (b/c возможного переполнения буфера).

Возможно, вы получите лучшие результаты с помощью собственного анализатора. Он может отображаться как больший исходный код, но он дает вам возможность контролировать и расширять ваш код именно так, как нужно, без ущерба для безопасности и скорости.

Обычный способ аккумулировать шестнадцатеричные цифры по одному, как вы читаете их и создать соответствующее целое число:

hexDigit = one letter from "ABCDEF" remapped to a number within 0-15 
accumulating_number= accumulating_number * 16 + hexDigit 

Вот маленький автономный анализатор как полный пример. Он принимает верхний и нижний регистр и игнорирует любое нерастворимое шестнадцатеричный символ (так что вы можете использовать пробел или запятые для лучшей читаемости в источнике):

#include <stdio.h> 

#define SPLIT_CHAR_SIZE 8 // size of the hex numbers to parse (eg. 6 for RGB colors) 

void do_something_with(unsigned int n) 
{ 
    printf("%08X ",n); 
} 

int main(int argc, char** argv) 
{ 
    FILE* fp= (argc!=2) ? stdin : fopen(argv[1],"r"); 
    if(!fp) { fprintf(stderr,"Usage: %s fileToRead\n", argv[0]); return(-1); } 

    unsigned int i=0, accumulator=0; 
    char c; 
    while(!feof(fp)) // you could parse a c-string via fscanf() to handle other file contents 
    { 
     c= fgetc(fp); 

     // The "<<4" gives room for 4 more bits, aka a nibble, aka one hex digit, aka a number within [0,15] 
     if(c>='0' && c<='9') 
      accumulator= (accumulator<<4) | (c - '0'); 
     else if(c>='a' && c<='f') // lower case 
      accumulator= (accumulator<<4) | (c - 'a' + 10); 
     else if(c>='A' && c<='F') // upper case 
      accumulator= (accumulator<<4) | (c - 'A' + 10); 
     else 
      continue; // skip all other (invalid) characters 

     // When you want to parse more than one hex number you can use something like this: 
     if(++i % SPLIT_CHAR_SIZE == 0) 
     { 
      do_something_with(accumulator); 
      accumulator= 0; // do not forget this 
     } 
    } 

    printf("\n"); 
    return 0; 
} 

Если вы даете этот анализатор это следующим образом (как-то странно) содержимое файла :

ca 53, 
FF 00 
aa bb cc dd 

то функция do_something_with() будет выводить следующее:

CA53FF00 AABBCCDD 
Смежные вопросы