2012-03-18 2 views
0

Я пытаюсь читать во входном файле 64 бит за раз, а затем делать некоторые вычисления на этих 64 битах, проблема в том, что мне нужно преобразовать ascii-текст в шестнадцатеричный персонажи. Я искал вокруг, но ни один из ответов, как представляется, не работает для моей ситуации.C читать X байтов из файла, при необходимости заполнить

Вот что у меня есть:

int main(int argc, int * argv) 
{ 
    char buffer[9]; 
    FILE *f; 
    unsigned long long test; 

    if(f = fopen("input2.txt", "r")) 
    { 
    while(fread(buffer, 8, 1, f) != 0) //while not EOF read 8 bytes at a time 
    { 
     buffer[8] = '\0'; 
     test = strtoull(buffer, NULL, 16); //interpret as hex 
     printf("%llu\n", test); 
     printf("%s\n", buffer); 
    } 
    fclose(f); 
    } 
} 

Для входа, как это:

"тестирование строки в шестнадцатеричном преобразования"

я получаю результаты, как это:

0 
testing 
0 
string t 
0 
o hex co 
0 nversion 

Где бы я мог ожидать:

74 65 73 74 69 6e 67 20 <- "testing" in hex 
testing 

73 74 72 69 6e 67 20 74 <- "string t" in hex 
string t 

6f 20 68 65 78 20 63 6f <- "o hex co" in hex 
o hex co 

6e 76 65 72 73 69 6f 6e <- "nversion" in hex 
nversion 

Может ли кто-нибудь увидеть, где я ошибся?

ответ

1

strtoull преобразует число, представленное строкой в ​​unsigned long long. Ваш ввод этой функции (например, «тестирование») не имеет смысла, поскольку это должно быть число.

printf("%llu\n", strtoull("123")); // prints 123 

Чтобы получить результат, который вы хотите, вы должны напечатать каждый символ строки, как это:

for(int i=0; i<8; i++) 
     printf("%02X ", (unsigned char) buffer[i]); 
+0

ничего себе, не знаю, как я проглядел, что, как я мог бы идти о преобразовании текста ASCII в соответствующие шестнадцатеричные байт тогда? –

+0

@Hunter: см. Мое редактирование – thumbmunkeys

+0

Спасибо, это было именно то, что я догонял. –

1

Функция strtoull (с 16) преобразует HEX строку числа, а не ASCII полукокса в Строка HEX.

Чтобы напечатать символ в виде HEX, вы должны сделать что-то вроде printf("%02x ",buffer[0]);

0

Вы можете попробовать делать getchar() 8 раз (каждое значение, возвращаемое getchar 1 байт = 8 бит), а затем с помощью atoh или что-то - я Я даже не уверен, что существует atoh, но запрещаем делать что-то вроде atoi, а затем itoh .. или написать собственный пароль для его преобразования.

1

strtoull() Преобразует строку, которая находится в шестнадцатеричном формате (например, 0xFFAABBEE) в его целочисленный формат.

Что вам действительно нужно, это функция, чтобы преобразовать строку в шестнадцатеричную строку, например:

char *strToHex(const char *input) 
{ 
    char *output = calloc(1, strlen(input) * 3 + 1); 

    char *o = output; 
    int i = 0; 

    for (; input[i] != '\0'; o += 3, i++) 
    { 
     sprintf(o, "%.2X ", input[i]); 
    } 

    // don't forget to free output! 
    return output; 
} 
1

Рассмотрите возможность использования limits.h, а также.

Я пошел немного за борт, но, возможно, некоторые из этого подходит:

Edit: [
Ehrmf. Возможно, определение BITS_ULL более подходит вашему поиску.
I.e.что-то в направлении:

#define BITS_ULL (sizeof(unsigned long long) * CHAR_BIT) 
#define BYTE_ULL (sizeof(unsigned long long)) 

А потом прочитал BYTE_ULL байт, но делают Shure проверить размер прочитанных байт, а не если -1, как последний может быть разбивали. Я немного не уверен, что вы подразумеваете под «вычислениями» на битах чтения.

Вы можете считывать байты BYTE_ULL и передавать в unsigned long long по адресу буфера [0] или смещать бит, принимая во внимание порядок байтов. Или бывшие и сортированные байты с указателем на символ.

Также Обратите внимание, что я использовал len вместо нулевого конца/строки C.

О, это много веселья :) - Я учусь, и такой взлом - это рай.
]

#include <stdio.h> 
#include <limits.h> /* BITS */ 
#include <ctype.h> /* isprint() */ 

#define CHUNK_BITS 62 
#define CHUNK_CHAR (CHUNK_BITS/CHAR_BIT) 
#define HEX_WIDTH 2 

/* print len hex values of s, separate every sep byte with space, 
* but do not add trailing space. */ 
void prnt_cshex(const char *s, int len, int sep) 
{ 
    const unsigned char *p = (const unsigned char*)s; 
    int i; 

    for (i = 1; i <= len; ++p, ++i) 
     fprintf(stdout, 
       "%02x" 
       "%s", 
       *p, 
       (i < len && !((i)%sep) ? " " : "")); 
} 

/* Print len bytes of s, print dot if !isprint() */  
void prnt_csbytes(const char *s, int len) 
{ 
    int i = 0; 

    for (i = 0; i < len; ++s, ++i) 
     fprintf(stdout, 
       "%c", 
       (isprint(*s) ? *s : '.')); 
} 

/* Pass file as first argument, if none, use default "input.txt" */ 
int main(int argc, char *argv[]) 
{ 
    const char *fn = "input.txt"; 
    FILE *fh; 
    char buffer[CHUNK_CHAR]; 
    const char *p = &buffer[0]; 
    size_t k; 

    if (argc > 1) 
     fn = argv[1]; 

    if ((fh = fopen(fn, "rb")) == NULL) { 
     fprintf(stderr, " * Unable to open \"%s\"\n", fn); 
     goto fail_1; 
    } 

    fprintf(stdout, 
     "Processing \"%s\"\n" 
     "Chunks of %d bytes of %d bits = %d bits\n", 
     fn, 
     CHUNK_CHAR, CHAR_BIT, CHUNK_CHAR * CHAR_BIT); 

    if (CHUNK_BITS != CHUNK_CHAR * CHAR_BIT) { 
     fprintf(stdout, 
     "%d bits chunk requested. Won't fit, trunkated to\n" 
      "%d * %d = %d\n" 
     "%d bits short.\n\n", 
     CHUNK_BITS, 
     CHUNK_CHAR, CHAR_BIT, CHUNK_BITS/CHAR_BIT * CHAR_BIT, 
     CHUNK_BITS - CHUNK_CHAR * CHAR_BIT); 
    } 

    while ((k = fread(buffer, 1, CHUNK_CHAR, fh)) == CHUNK_CHAR) { 
     prnt_cshex(p, CHUNK_CHAR, HEX_WIDTH); /* Print as hex */ 
     printf(" "); 
     prnt_csbytes(p, CHUNK_CHAR);  /* Print as text */ 
     putchar('\n'); 
    } 

    if (!feof(fh)) { 
     fprintf(stderr, " * Never reached EOF;\n"); 
     goto fail_close; 
    } 

    /* If input file does not fit in to CHUNK, report this */  
    if (k > 0) { 
     printf("%d byte tail: '", k); 
     prnt_csbytes(p, k); 
     printf("'\n"); 
    } 

    fclose(fh); 

    return 0; 
fail_close: 
    fclose(fh); 
fail_1: 
    return 1; 
} 
Смежные вопросы