фред и фрайт в С - PullRequest
       45

фред и фрайт в С

1 голос
/ 28 января 2012

Я пытаюсь создать программу, которая создает и читает двоичный файл, который содержит «элементы структуры»; подскажите пожалуйста, что я сделал не так? Я получил ошибки, говорящие, что "s" не является указателем в функции fread () ... поэтому я объявил ELEM * s; вместо ELEM s;

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

typedef struct element{
    char name[80];
    int p;
}ELEM;

void create()
{
    FILE *f;
    int d=0;
    char c;
    ELEM *s;
    f=fopen("file.bin","wb");
    do{
    printf("Add elements to file?: (y/n)");
    fflush(stdin);
    scanf("%c",&c);
    if (c=='y')
    {
        printf("Name=");
        gets((*s).name);
        printf("P=");
        scanf("%d",(*s).p);
        fwrite(s,sizeof(ELEM),1,f);
    }
    } while(d==0);
    fclose(f);
}

void show()
{
    FILE *f;
    ELEM *s;
    f=fopen("file.bin","rb");
    while(feof(f)!=NULL)
    {
        fread(s,sizeof(ELEM),1,f);
        puts((*s).name);
        printf("\t%d\n",(*s).p);
    }
    fclose(f);
}

void add()
{
    FILE *f;
    int d=0;
    char c;
    ELEM *s;
    f=fopen("file.bin","ab");
    do{
    printf("Add elements to file?: (y/n)");
    fflush(stdin);
    scanf("%c",&c);
    if (c=='y')
    {
        printf("Name=");
        gets((*s).name);
        printf("P=");
        scanf("%d",(*s).p);
        fwrite(s,sizeof(ELEM),1,f);
    }
    } while(d==0);
    fclose(f);
}


/*void function()
{

}*/

int main()
{
    int k=0,r;
    do{
        printf("1 - create file\n2 - add elements to fil\n3 - show elements\n4 - put unique elements in another file\n5 - exit program\n");
        scanf("%d",&r);
        switch(r)
        {
            case 1 : create(); break;
            case 2 : add(); break;
            case 3 : show(); break;
            case 4 : printf("Function not defined!\n"); break;
            case 5 : k=1; break;
            default : printf("Command unrecognized!\n");
        }
    } while(k==0);
    return 0;
}

Ответы [ 5 ]

3 голосов
/ 28 января 2012

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

ELEM s;

/* ... */

fwrite(&s,sizeof(ELEM),1,f);
       ^

В качестве альтернативы, в вашем текущем коде вы должны сделать это:

ELEM *s = calloc(1, sizeof *s);
0 голосов
/ 28 января 2012

Вы должны были выделить указатель на структуру ELEM. Предполагая, что это C:

 ELEM *s = malloc(sizeof(ELEM));

Если это C ++, просто добавьте приведение впереди

 ELEM *s = (ELEM*) malloc(sizeof(ELEM));
0 голосов
/ 28 января 2012

Ну, ваши проблемы в scanf. scanf должен получить указатель, поэтому измените (*s).p на &(*s).p (или даже &s->p)

0 голосов
/ 28 января 2012

Вы не выделяете указатель s в вашей функции create. Вы, вероятно, хотите что-то вроде

 s = malloc(sizeof(*s));
 memset (s, 0, sizeof(*s));

и т.д.

И вы действительно должны научиться компилировать с gcc -Wall -g и использовать отладчик gdb.

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

0 голосов
/ 28 января 2012

Первый параметр, переданный fwrite , должен быть адресом, а переменная, адрес которой вы передаете, должна иметь достаточно памяти для хранения количества объектов, которые вы планируете прочитать.

Таким образом, есть два способа:

Создание переменной в стеке:

Вы размещаете переменную в стеке и передаете ее адрес fwrite

ELEM s;
fwrite(&s,sizeof(ELEM),1,f);

или

Динамическое выделение памяти:

ELEM *s;   

Должен быть выделен объем памяти, эквивалентный для хранения объектов типа ELEM, которые выхочу почитать.

ELEM *s = malloc(sizeof *s);

В этом случае не забудьте освободить память после того, как вы ее сделали:

free(s);
...