C:读二进制问题

时间:2014-05-05 00:55:55

标签: c linked-list binaryfiles

我知道fopen可以执行" rb" (读二进制)和" wb" (写二进制文件)以二进制文件读写。这就是我在这样的文件中阅读的内容:

(编辑:这里是那些想知道的人的结构)

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

这是我的变量:

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;

......以下是主要内容:

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");
    }
}

这是我分配内存以存储信息的地方。

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);
}
}

在我的程序中,在while循环之后的fread部分发生了分段错误。数据以

的形式保存为二进制文件
fwrite(&lastName,sizeof(SREC),totalCount,fout);

每次放入记录时,totalCount都会上升,每次删除记录时,记录都会下降。所有这些都有效。它只是读取字节并尝试使其不会出现我遇到问题的段错误。我做错了什么?

再次重申一下,这是问题代码,它会产生一个段错误:

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

2 个答案:

答案 0 :(得分:2)

问题是循环条件:

while(!feof(fptr))

feof()仅在您读取文件末尾时返回非零值,而不是当文件指针位于文件末尾时。这意味着你的循环将比它应该运行一次。

答案 1 :(得分:2)

这一行

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

正在将数据读入temp的位置。您希望将数据读入您(可能)为temp分配的内存中。删除&

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