我知道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);
答案 0 :(得分:2)
问题是循环条件:
while(!feof(fptr))
feof()
仅在您读取文件末尾时返回非零值,而不是当文件指针位于文件末尾时。这意味着你的循环将比它应该运行一次。
答案 1 :(得分:2)
这一行
fread(&temp,sizeof(SREC),1,fptr);
正在将数据读入temp
的位置。您希望将数据读入您(可能)为temp分配的内存中。删除&
fread(temp,sizeof(SREC),1,fptr);