2009-10-16 4 views
1

현재 텍스트 파일에서 16 진수 값을 읽으려고합니다.16 진수 값 읽기 (C)

이 진수의 여러 줄 수 있고 각 행이 필요한만큼 될 수 있습니다와 같은 fscanf과 unsigned char line[500]

f53d6d0568c7c7ce 

    1307a7a1c84058 

    b41af04b24f3eb83ce 

는 현재, 내가 16 진수 값을 읽을 함께 간단한 루프를 넣어 :

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

현재로서는 첫 번째 행만 읽습니다. 또한, 무작위로 500을 던지기 만하면 읽을 수있는 최선의 방법은 아닙니다.

나는 또는 이와 비슷한 것을 가지고 sscanf을 사용할 수 있다고 가정하고 있었다. 그러나 이것이 최선의 접근 방법이 될지 확신 할 수 없었습니다.

누구든지 올바른 방향으로 나를 가리킬 수 있다면, 크게 감사하겠습니다.

답변

3

오른쪽 궤도에 fgets()sscanf()으로 있습니다. 그렇게하면 모든 것을 적절하게 조정할 수 있습니다. 데이터가 실제로 해당 형식 인 경우 sscanf()이 지나치게 많을 수 있습니다. 당신은 빠른 변환 루프를 직접 작성하고 모든 가변적 인 함수 호출을 저장할 수 있습니다.

+1

그냥'은'ctype.h' 헤더에'의 ToUpper()'와'tolower를()를 기억 16 진수 변환기. 대소 문자를 구분하지 않는 16 진수 데이터를 지원하는 것은 결코 나쁜 일이 아닙니다. –

+0

@Chris, 절대적으로; 좋은 전화. –

3

sscanf는 느리기 때문에 (라이브러리 호출, 메모리 사용 및 과용)주의하십시오. 또한 그것은 너무 위험합니다 (가능한 버퍼 오버런의 b/c).

당신은 아마도 당신 자신의 파서로 더 나은 결과를 얻을 것입니다. 더 큰 소스 코드로 표시 될 수 있지만 보안 및 속도를 저하시키지 않으면 서 필요에 따라 코드를 정확하게 제어하고 확장 할 수있는 기회를 제공합니다.

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

전체 예로서 작은 독립 파서입니다 :

일반적인 방법은 당신이 그들을 읽을 때 하나를 사용하여 16 진수 하나를 축적하고 해당 정수를 구축하는 것입니다. 그것은 하부 및 상부 케이스 받아서는 비 진수 문자 (그래서 당신은 소스에 더 나은 가독성을 위해 공백이나 쉼표를 사용할 수 있습니다) 무시 :

#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