2016-09-13 7 views
1

Я пытаюсь объединить часть структуры с шестнадцатеричными значениями. Я пробегаю каждый байт в цикле и конвертирую в hex, тогда я хочу объединить все шестнадцатеричные строки в одну длинную строку.C Конкатенация строки во время цикла

Однако, я заканчиваю только одним значением в конце цикла. По какой-то причине строка не конкатенируется правильно. Любая идея, что я делаю неправильно?

typedef struct OPTIONS_STR 
{ 
    int max; 
    int printName; 
} OPTIONS; 

void set_default_options(OPTIONS *options) 
{ 
    options->max = -1; 
    options->printName = 0; 
} 

void do_file(FILE *in, FILE *out, OPTIONS *options) 
{ 
    char ch; 
    int loop = 0; 
    char buf[81]; 
    buf[0] = '\0'; 
    int sz1; 
    int sz2; 
    int sz3; 

    int seeker = offsetof(struct myStruct, contents.datas); 

    //find total length of file 
    fseek(in, 0L, SEEK_END); 
    sz1 = ftell(in); 

    //find length from beggining to struct beginning and minus that from total length 
    fseek(in, seeker, SEEK_SET); 
    sz2 = sz1 - ftell(in); 

    //set seek location at beginning of struct offset 
    fseek(in, seeker, SEEK_SET); 

    sz3 = sz2 + 1; 
    char buffer[sz3]; 
    char msg[sz3]; 

    buffer[0] = '\0'; 

    while (loop < sz2) 
    { 
     if (loop == sz2) 
     { 
      break; 
     } 

     fread(&ch, 1, 1, in); 
     sprintf(msg, "%02X", (ch & 0x00FF)); 
     strcpy(buffer, msg); 

     ++loop; 
    } 
    printf("%s\n", buffer); 
} 

int main(int argc, const char * argv[]) { 

    OPTIONS options; 
    set_default_options(&options); 

    const char *current = "/myfile.txt"; 
    FILE *f = fopen(current, "rb"); 
    do_file(f, stdout, &options); 
    fclose(f); 

}; 
+3

'strcpy()' копирует исходную строку в строку назначения, перезаписывая ее предыдущее содержимое. Возможно, вам понадобится 'strcat()'. –

+4

'int index = 0; index + = sprintf (& buffer [index], "% 02X", (ch & 0x00FF)); ' – LPs

+3

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

ответ

3

Использование strcat вместо strcpy. Это должно решить вашу проблему.

Для эффективности посмотреть в использовании указателя записи как char *p = buffer и продвигать позицию записи с чем-то вроде p += sprintf(p, "%02X", (ch & 0x00FF))

Кроме того, ваш if(loop == sz2) break чека является бесполезным дубликатом while(loop < sz2) проверки. Цикл while не будет выполняться, если loop равен или больше sz2.

Также интересно, почему вы используете fread, когда вам нужен только один символ. fgetc или getc, кажется, лучший выбор.

Кроме того, независимо от того, используете ли вы fread или getc, вам необходимо проверить, в конце файла. Что делать, если файл не содержит sz2 байтов? Потому что все современные системы многопроцессорны и многопользовательские, поэтому кто-то может сократить файл после вызова ftell. Вы никогда не должны принимать вещи, потому что, даже если вы просто проверили это, это может измениться. Создание этого предположения является причиной ошибок TOCTTOU (время проверки на время использования).

+0

Привет, Зан, все это, кроме указателя. Как включить это в свой код? Я объявляю char * p вверху, когда создается буфер? –

+0

@Ke. Он должен появиться после создания буфера, поэтому у него есть что сказать. И он не может находиться внутри цикла или он будет сброшен в буфер для каждого цикла. –

+0

ok Я думаю, что теперь я получаю указатель, и как работает sprintf, поэтому спасибо за это, теперь я пытаюсь добавить некоторые дополнительные символы в массив «\ n \ t \ t \ t \ t», и он не кажется чтобы работать, любая идея, почему? –

-1

В do_file() вы копируете шестнадцатеричное значение для одного байта в цикле while. Таким образом, вы должны перейти к следующему байту массива символов buffer с каждой итерацией цикла while, то есть buffer++ или strcpy(buffer[loop], msg);

+0

Ваш метод может работать, но вам нужно «loop * 2' –

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