2013-02-28 2 views
0

С fwrite я пишу целые структуры? w.e находится в f1 и f2? Любая помощь будет оцененаCструкции будут работать?

typedef struct { 
    int field1; 
    int field2; 
}mystruct; 

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

    int size=2; 
    mystruct structarray [size]; 
    int i=0; 
    for (i=0;i<size;i++) 
    { 
     structarray[i]=calloc(1,sizeof(mystruct)); 
    } 

    FILE *F1; 
    if (fopen("structfile","wt")==NULL){ 
     err_sys("cannot be opened"); 
    } 

    i=0; 
    for (i=0;i<size;i++) 
    { 
     structarray[i].field1=i; 
    } 

    fwrite(structarray[0].field1,sizeof(mystruct),size,F1); 
    fclose(F1); 
} 
+0

Я предполагаю, что это не ваша проблема, но вы уже ставите две структуры 'mystruct' статически - вам не нужно вызывать' calloc', чтобы выделить больше в куче. – aardvarkk

+0

Я бы, вероятно, открыл файл с «wb» для записи двоичного файла, так как вы не печатаете в формате fprintf. Кстати, нормально писать/читать двоичные данные, и это похоже на то, что вы делаете. Просто не пытайтесь читать двоичные данные в виде «текста», потому что в ваших двоичных данных могут быть 0 значений, которые будут путать строковые функции std C. –

ответ

1

Концептуально ваш подход будет работать. Однако есть несколько проблем с кодом:

(1) structarray объявлен как автоматическая переменная (выделенная в стеке). Нет причин для вызова calloc() для каждого элемента массива; массив уже полностью выделен. Возможно, вы хотели инициализировать элементы массива (например, memset() и т. Д.).

(2) fopen() возвращает указатель на файл, который был открыт, но вы не назначаете возвращаемое значение F1. В результате F1 остается неинициализированным, поэтому звонок fwrite() не будет работать.

(3) Если ваше намерение состоит в том, чтобы сохранить полный массив структур в файл (в отличие от конкретных элементов), измените вызов fwrite() следующим образом:

fwrite(structarray, sizeof(mystruct), size, F1); 

(4) Всегда проверяйте возвращаемое значение от fwrite(), чтобы убедиться, что это удалось.

+0

Всегда проверяйте значение 'fwrite', а также' fclose'. Например, в случае полного состояния диска вы можете получить 'fwrite' для успеха (это просто запись в буферах) и' fclose' сбой. – 6502

+0

«Концептуально ваш подход будет работать» - Нет, это неопределенное поведение ... попытка конвертировать значение 'structarray [0] .field1' в указатель. –

+0

@ 6502 fclose скопирует буфер памяти stdio в памяти в буфер диска ядра, но это не обнаружит диск полностью, если вы не сказали системе делать синхронные записи. –

1

structarray[0].field1 является int, но первый аргумент fwrite - void*. Используйте

fwrite(structarray, sizeof(mystruct), size, F1); 

или я предпочитаю

fwrite(structarray, sizeof *structarray, size, F1); 

, поскольку он не связан с типом structarray и снижения сцепления является хорошей вещью. Можно даже просто сделать

fwrite(structarray, sizeof structarray, 1, F1); 

, пока structarray действительно массив, а не указатель.

Вы должны проверить возвращаемое значение fwrite. И компилировать с уровнем предупреждения установлен высокий ... компилятор должен предупредить вас о вашей попытке передать int в fwrite, а также

structarray[i]=calloc(1,sizeof(mystruct)); 

который не является законным ... structarray[i] является mystruct но calloc возвращает указатель. См. Комментарий aardvarkk по вашему вопросу. Он также должен сказать вам, что вы использовали F1, даже не устанавливая его.

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