2015-06-01 4 views
0

Может ли кто-нибудь сказать мне, почему эта функция не работает? Я просто не могу получить его ...fwrite() не работает, чтобы написать целое число в двоичном файле

void writeRegister(FILE *arq, Book *L){ //writes in actual file position 
    char c = '|'; 
    int sizeRegWrite = reglen(L); //reglen() returns the size of Book 
    fwrite(&sizeRegWrite, sizeof(int), 1, arq); 

    fwrite(L->TITLE, sizeof(char), strlen(L->TITLE), arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->AUTHOR, sizeof(char), strlen(L->AUTHOR), arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->PUBLISHER, sizeof(char), strlen(L->PUBLISHER), arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->YEAR, sizeof(int), 1, arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->LANGUAGE, sizeof(char), strlen(L->LANGUAGE), arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->PAGES, sizeof(int), 1, arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 

    fwrite(L->PRICE, sizeof(float), 1, arq); 
    fwrite(&c, sizeof(char), 1, arq); //writing delimiter 
     return; 
} 

структура книги объявлен как это:

typedef struct { 
    char *TITLE; 
    char *AUTHOR; 
    char *PUBLISHER; 
    int YEAR; 
    char *LANGUAGE; 
    int PAGES; 
float PRICE; 
} Book; 

Главная

int main() { 
FILE *arq = fopen("BD_books2.bin", "rb+"); 
if(arq == NULL) 
    printf("Error while opening file!!!"); 

Book L; 
readData(&L); //Reads all fields from keyboard and places in Book. Working properly 
writeRegister(arq, &L); 

system("pause"); 
return 0; 

}

I должны использовать эти указатели внутри ruct, поэтому я не могу их удалить. Кстати, моя проблема связана только с теми integers и float.

Эта функция работает только в том случае, если я записываю все целые числа и плавающие числа (YEAR, PAGES и PRICE) с fprintf(), но я пишу его в двоичном файле и, конечно, хочу записать его в двоичном формате, поэтому я пытаюсь использовать fwrite().

Другое дело: компилятор указывает incompatible type for argument 1 of 'fwrite' на этой линии: fwrite(L->PRICE, sizeof(float), 1, arq);

Может кто-нибудь объяснить мне, что происходит? Моя программа вылетает, когда она пытается записать в файл ...

+0

опущено 'неудобно readData' и' reglen' может хорошо играть в эту. Любые причины, в частности, вы решили не включать их, если не по какой-либо причине, кроме как закончить [MCVE] (https://stackoverflow.com/help/mcve)? – WhozCraig

+0

BTW: Вместо 'fwrite (& sizeRegWrite, sizeof (int), 1, arq);', рассмотрим модель 'fwrite (& var, sizeof var, 1, arq);' – chux

+1

Анализ синтаксического анализа звучит как полный кошмар; вы смешиваете двоичные данные с разделителями ASCII. Могу ли я предложить либо придерживаться текстового формата (используя 'fprintf' для записи каждой строки и' fscanf' для чтения файла), либо более структурированный двоичный формат (например, строки с префиксом длины)? – nneonneo

ответ

6

Первый параметр fwrite ожидает указатель.

линия, такие как следующие:

fwrite(L->PAGES, sizeof(int), 1, arq); 

должен быть записан следующим образом:

fwrite(&(L->PAGES), sizeof(int), 1, arq); 

Sames идет за год и ЦЕН членов этой структуры

fwrite(&(L->YEAR), sizeof(int), 1, arq); 
... 
fwrite(&(L->PRICE), sizeof(float), 1, arq); 

Примечания, вы не нужно делать одно и то же изменение для TITLE, PUBLISHER и AUTHOR, потому что тип этих полей участника уже указатели (char *).

+0

Ох, теперь я вижу !! К вам так много! – Quik19

2

Сигнатура fwrite является

std::size_t fwrite(const void* buffer, std::size_t size, std::size_t count, std::FILE* stream); 

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

fwrite(L->YEAR, sizeof(int), 1, arq); 
fwrite(L->PAGES, sizeof(int), 1, arq); 
fwrite(L->PRICE, sizeof(float), 1, arq); 

Они должны быть

fwrite(&(L->YEAR), sizeof(int), 1, arq); 
fwrite(&(L->PAGES), sizeof(int), 1, arq); 
fwrite(&(L->PRICE), sizeof(float), 1, arq); 

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

if (fwrite(&(L->YEAR), sizeof(int), 1, arq) != 1) 
{ 
    // Deal with the error condition. 
} 
+0

@ R Sahu - Спасибо за ваш ответ! К сожалению, я не могу выбрать 2 ответа как лучший ... – Quik19

+0

@ Quik19, все в порядке. У вас есть необходимый ответ. Это самая важная часть. –

1

Вы должны передать адрес L->YEAR в fwrite

fwrite(L->YEAR, sizeof(int), 1, arq); 

fwrite(&(L->YEAR), sizeof(int), 1, arq); 
0

следующий код:

1) eliminates the bad practice of typedef'ing a struct 
2) removed the mis-leading all caps of the struct field names 
3) contains the needed #includes 
4) contains the needed prototypes for the external (in another file) functions 
5) checks for the worst of the many possible runtime errors 
6) replaces the mis-leading 'L' with a meaningful name 
7) modifies the file pointer variable to a commonly known name 

suggest compiling with all warnings enabled (and fix the warnings) 
for gcc, at a minimum, use '-Wall -Wextra -pednatic' 


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 



struct Book 
{ 
    char *title; 
    char *author; 
    char *publisher; 
    int year; 
    char *language; 
    int pages; 
    float price; 
}; 

int reglen(struct Book *); 
int readData(struct Book *); 


void writeRegister(FILE *fp, struct Book *myBook) 
{ //writes in actual file position 
    char c = '|'; 
    int sizeRegWrite = reglen(myBook); //reglen() returns the size of Book 
    fwrite(&sizeRegWrite, sizeof(int), 1, fp); 

    fwrite(myBook->title, sizeof(char), strlen(myBook->title), fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(myBook->author, sizeof(char), strlen(myBook->author), fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(myBook->publisher, sizeof(char), strlen(myBook->publisher), fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(&(myBook->year), sizeof(int), 1, fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(myBook->language, sizeof(char), strlen(myBook->language), fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(&(myBook->pages), sizeof(int), 1, fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 

    fwrite(&(myBook->price), sizeof(float), 1, fp); 
    fwrite(&c, sizeof(char), 1, fp); //writing delimiter 
    return; 
} // end function: writeRegister 


int main(void) 
{ 
    FILE *fp = fopen("BD_books2.bin", "rb"); 
    if(fp == NULL) 
    { 
     perror("fopen for BD_books2.bin failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 

    struct Book myBook; 
    int goodRead = readData(&myBook); //Reads all fields from keyboard and places in Book. Working properly 
    if(goodRead) 
    { 
     writeRegister(fp, &myBook); 
    } 

    system("pause"); 
    return 0; 
} // end function: main 
Смежные вопросы