2015-03-03 1 views
1

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

Создание файлов данных в ascii прошло без сучка и задоринки. Я переключился с использования fwrite на использование fprintf с указанным форматом, заканчивающимся \ n для новой строки.

FPFPF = fopen(flightStr, "w+"); 

    if (FPFPF != NULL) 
    { 
     for (i = 0; i < FlightInfo[flightnum].endFrameIndex; i++) 
     { 
      FlightEntries[flightnum][i].local_z += DeltaAlt; 

      //if (fwrite (&FlightEntries[flightnum][i], sizeof (FLIGHT_ENTRY_TYPE), 1, FPFPF) !=1) 
      if (fprintf (FPFPF, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", 
       FlightEntries[flightnum][i].local_x, 
       FlightEntries[flightnum][i].local_y, 
       FlightEntries[flightnum][i].local_z, 
       FlightEntries[flightnum][i].pitch, 
       FlightEntries[flightnum][i].roll, 
       FlightEntries[flightnum][i].heading, 
       FlightEntries[flightnum][i].gearpos, 
       FlightEntries[flightnum][i].flappos, 
       FlightEntries[flightnum][i].speedbrakepos, 
       FlightEntries[flightnum][i].canopypos, 
       FlightEntries[flightnum][i].afterburnerOn, 
       FlightEntries[flightnum][i].kias, 
       FlightEntries[flightnum][i].time) !=1) 
      { 
       WE++; 
      } 
     } 

     fclose(FPFPF); 
    } 

Это сработало отлично. вы можете увидеть, что старый fwrite закомментирован.

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

if (load) 
     { 
      for (i = 0; i < MAX_FLIGHT_ENTRIES; i++) 
      {    
       // If the file end is found before it should be, set values to defaults 
       // and save the file 
       if (feof(pFile)) 
       { 
        FlightInfo[fileIndex].endFrameIndex = i - 1; 
        break; 
       } 
       else 
       { 
        //fread (&FlightEntries[fileIndex][i], sizeof (FLIGHT_ENTRY_TYPE), 1, pFile); 

        fscanf (pFile, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n", 
         &FlightEntries[fileIndex][i].local_x, 
         &FlightEntries[fileIndex][i].local_y, 
         &FlightEntries[fileIndex][i].local_z, 
         &FlightEntries[fileIndex][i].pitch, 
         &FlightEntries[fileIndex][i].roll, 
         &FlightEntries[fileIndex][i].heading, 
         &FlightEntries[fileIndex][i].gearpos, 
         &FlightEntries[fileIndex][i].flappos, 
         &FlightEntries[fileIndex][i].speedbrakepos, 
         &FlightEntries[fileIndex][i].canopypos, 
         &FlightEntries[fileIndex][i].afterburnerOn, 
         &FlightEntries[fileIndex][i].kias, 
         &FlightEntries[fileIndex][i].time); 
       } 
      } 

      FlightInfo[fileIndex].endFrameIndex = i - 1; 

     } 

Там немного из другой проверки перед тем Pfile открывается и нагрузка является BOOL, который устанавливается, если мы будем делать больше, чем просто увидеть, если файл существует. Если это имеет значение, все значения структуры FlightInfo являются float, за исключением local_x, local_y и local_z, которые являются двойными. Есть ли что-то, что здесь явно не так очевидно? Он компилируется и запускается без ошибок до тех пор, пока этот блок кода не будет вызван, а затем просто сработает.

+1

Возможно, я ошибался, но моя первая попытка состояла в том, чтобы использовать паратет здесь: '& FlightEntries [fileIndex] [i] .local_x' =>' & (FlightEntries [fileIndex] [i] .local_x) '. Я всегда забываю, что порядок оценки и использование paranthesis не могут быть ошибочными.^ – UniversE

+1

@UniversE: Эти parens явно излишни. – Deduplicator

+0

Не имеет значения для 'fprintf', являются ли они' float' или 'double' из-за промо-акций, но это очень важно для' fscanf'. – Deduplicator

ответ

2

Не имеет значения fprintf ли вы передаете float или double из-за промоакций по умолчанию, выполненных для вариативных аргументов.

Но это имеет очень много для fscanf пройти ли вы float* или double*:

См http://man7.org/linux/man-pages/man3/scanf.3.html для флагов: символы модификаторов

Следующего типа могут появиться в спецификации преобразования :

l Указывает либо на то, что преобразование будет одним из d, i, o, u, x, X или n, а следующий указатель - указатель на длинный int или unsigned long int (вместо int), или что преобразование будет одним из e, f или g и следующего указатель - указатель на двойной (а не плавающий). Указание двух символов l равно , эквивалентным L. Если используется с% c или% s, соответствующий параметр рассматривается как указатель на широкий символ или широковещательную строку соответственно.

На самом деле, вы должны прочитать эту целую страницу руководства, есть и другие интересные подводные камни.

В качестве недостатка, l -модификатор не действует для fprintf с помощью указателя с плавающей запятой.

+0

Это все! Раньше я был таким умным ... ну, почти так или иначе. Хороший глаз! –

+0

@Deduplicator. Я думаю, я не совсем понимаю, как бы применить это к моему формату ... Предполагается, что я должен быть числом или добавить литерал в строку формата? так что первые три будут% d6,% f6 или должны быть% dl или% fl? Я никогда не использовал их раньше ... 6 исходит из того, сколько десятичных знаков записано в файле для каждой записи в каждой строке. –

+1

Кажется, вы должны внимательно прочитать эту страницу. Формат: «' '' '' '' для подавления присваивания '[максимальная ширина поля] [модификатор типа] преобразование "для' fscanf'. Возможно, вам лучше эта ссылка лучше: http://en.cppreference.com/w/c/io/fprintf – Deduplicator