Вопрос

I know that fopen can perform an "rb" (read binary) and "wb" (write binary) to read and write in binary files. This is what I have for reading in such a file:

(EDIT: here's the struct for those who want to know)

typedef struct student
{
    char lname[ 10 ], initial[1], fname[ 10 ];
    unsigned long SID;
    float GPA;
    struct student *next;
} SREC;

Here's my variables:

FILE *fptr, *fout;
SREC *temp = NULL;
SREC *firstName = NULL;
SREC *lastName = NULL;
SREC *studentID = NULL;
SREC *grade = NULL;
char lname[10] = "";
char fname[10] = "";
char mid[1];
unsigned long SID = 0;
float GPA = 0.0;
char temp2[100];
char inString[100];
int servercmd = 0;
int fileOpen = 0;
int totalCount = 0;

...and the following is inside of main:

if ((fptr = fopen("data", "rb+")) == NULL)
{
    printf("No file detected. Creating...\n");
    if ((fout = freopen("data","wb+",stdout)) == NULL)
    {
        fprintf(stderr,"Cannot generate file!\n");
        exit(1);
    }
    else
        fclose(fout);
}
else
{
    if (!feof(fptr))
    {
        fileOpen = 1;
        insert_student(&temp," "," "," ",00000,0.00,1);
        while(!feof(fptr))
        {
            /* fscanf(fptr,"%s %s %c %d %f",lname,fname,&mid[0],&t1,&GPA); */

            fread(&temp,sizeof(SREC),1,fptr);

            /* Make sure it's not empty. */
            printf("Is it strcmp?\n");
            if (strcmp(temp->lname," ") != 0)
            {
                insert_student(&firstName,temp->lname,temp->initial,temp->fname,temp->SID,temp->GPA,1);
                insert_student(&lastName,temp->lname,temp->initial,temp->fname,temp->SID,temp->GPA,2);
                insert_student(&studentID,temp->lname,temp->initial,temp->fname,temp->SID,temp->GPA,3);
                insert_student(&grade,temp->lname,temp->initial,temp->fname,temp->SID,temp->GPA,4);
                totalCount++;
                printf("%d\n",totalCount);
            }
        }
        printf("Finished reading.\n");
    }
    else
    {
        printf("File is empty.\n");
    }
}

Here is where I'm allocating memory to store information.

void insert_student(SREC **studentPtr, char last[10], char init[1], char first[10], unsigned long SID, float GPA, int mode)
{
SREC *newNode;
SREC *previous;
SREC *current;

newNode = (SREC*)malloc(sizeof(SREC));

if(newNode != NULL) /*Make sure memory was available*/
{
    strcpy(newNode -> lname,last);
    strcpy(newNode -> initial,init);
    strcpy(newNode -> fname,first);
    newNode->SID = SID;
    newNode->GPA = GPA;
    newNode->next = NULL;

    previous = NULL;
    current = *studentPtr;

    /* Traverses list until end or larger data is found.
     * If order doesn't matter, only append to the end by
     * removing second condition or insert at the beginning
     * in constant time. */
    if (mode == 1) /*first name*/
    {
        while(current != NULL && strcmp(first,current->fname) > 0)
        {
            previous = current;
            current = current -> next;
        }
    }
    else if (mode == 2)
    {
        while(current != NULL && strcmp(last,current->lname) > 0)
        {
            previous = current;
            current = current -> next;
        }
    }
    else if (mode == 3)
    {
        while(current != NULL && SID > current->SID)
        {
            previous = current;
            current = current -> next;
        }
    }
    else if (mode == 4)
    {
        while(current != NULL && GPA > current->GPA)
        {
            previous = current;
            current = current -> next;
        }
    }

    if (previous == NULL) /*newNode is placed at the beginning*/
    {
        newNode -> next = *studentPtr;
        *studentPtr = newNode;
    }
    else /*newNode is placed in middle or end*/
    {
        previous -> next = newNode;
        newNode -> next = current;
    }

}
else
{
    printf("%s not inserted\n",last);
}
}

There's a segmentation fault occurring in my program upon the fread portion right after the while loop. Data is saved out as binary with

fwrite(&lastName,sizeof(SREC),totalCount,fout);

Each time a record is put in, totalCount goes up, and each time a record is deleted, it goes down. All that stuff works. It's just reading in the bytes and trying to make it not give a seg fault that I'm having a problem with. What am I doing wrong?

Again, to reiterate, this is the problem code which is getting a segfault:

fread(&temp,sizeof(SREC),1,fptr);
Это было полезно?

Решение

This line

fread(&temp,sizeof(SREC),1,fptr);

is reading data into the location of temp. You want to read data into the memory you have (presumably) allocated for temp. Remove the &

fread(temp,sizeof(SREC),1,fptr);

Другие советы

The problem is the loop condition:

while(!feof(fptr))

feof() returns non-zero only it you read past the end of file, not when file pointer is at the end of file. That means your loop will run one more time than it should.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top