【发布时间】:2019-05-11 17:56:18
【问题描述】:
我正在尝试制作一个 C 程序来接收电影列表并通过内存分配添加到其中,并且能够从列表中检索电影以及使用 txt 文件。 电影.txt 5 不可能完成的任务 行动 4 2008年 向上 行动 3 2012
我在命令行中运行后一直遇到错误,当菜单出现时,每当我输入一些内容时,它都会运行段错误。我现在无法访问调试器,虽然我认为这是我的指针或内存分配的问题,但我不确定是什么问题。
有人能指出正确的方向吗?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// limit definition
#define LIMIT 999
//movie structure
struct movie
{
char name[100];
char type[30];
int rating;
int releaseDate;
};
//reads file
void readFile(FILE *fp,struct movie* movieList[],int *noOfReviews)
{
char buffer[100];
int counter = 0;
struct movie* newNode;
fgets(buffer,LIMIT,fp);
*noOfReviews = atoi(buffer); // number of reviews in buffer
printf("%d",*noOfReviews); //prints reviews
while((fgets(buffer,LIMIT,fp)!=NULL) || (*noOfReviews > 0)) //if null or reviews greater than zero
{
if(counter % 4 == 0)
{
struct movie* tmpNode = (struct movie*)malloc(sizeof(struct movie)); //allocates memory
movieList[counter] = tmpNode;
newNode = tmpNode;
*noOfReviews--; // --#ofreviews
}
//copys struc into buffer
switch(counter % 4 )
{
case 0:
strcpy(newNode->name,buffer);
break;
case 1:
strcpy(newNode->type,buffer);
break;
case 2:
newNode->rating = atoi(buffer);
break;
case 3:
newNode->releaseDate = atoi(buffer);
break;
default:
printf("Exception\n");
break;
}
counter++;
}
}
//searches list
int searchList(struct movie* movielist[],char movieName[],int noOfMovies)
{
int counter = 0;
while(noOfMovies--)
{
if(strcmp(movielist[counter]->name,movieName) == 0) // if string compares to name
{
return counter;
}
counter++;
}
return -1;
}
//compares strings of name
int nameStrCmp(const void *a, const void *b)
{
return (strcmp(((struct movie*)a)->name,((struct movie*)b)->name));
}
// compares rating strings
int ratingStrCmp(const void * a, const void * b)
{
return (((struct movie*)a)->rating - ((struct movie*)b)->rating);
}
//displays the structure
void display(struct movie* movieList[],int n)
{
int i;
struct movie* searchRslt;
for(i = 0; i < n; i++)
{
searchRslt = movieList[i];// search result index of movies list
//prints struct information
printf("name:%s\n type:%s\n rating:%d\n releaseDate:%d\n",searchRslt->name,searchRslt->type,searchRslt->rating,searchRslt->releaseDate);
}
}
//main function
int main(int argc, char *argv[])
{
char buffer[100];
int noOfReviews;
struct movie* movieList[1000];
struct movie *searchRslt;
char mName[100];
if(argc <= 1)
{
printf("invalid");
return 0;
}
FILE *fp = fopen(argv[1],"r");
readFile(fp,movieList,&noOfReviews);
while(1)
{
//case selection menu
int input;
printf("Enter 1 to search for a movie.\n");
printf("Enter 2 to display the list of movies by name.\n");
printf("Enter 3 to display the list of movies by rating.\n");
scanf("%d",&input);
switch(input)
{
case 1:
printf("Enter movie name to search:");
scanf("%s",mName);
int index = searchList(movieList,mName,noOfReviews);
if(index < 0)
printf("Not found!!\n"); // if movie not found
else // gets movies
{
searchRslt = movieList[index];
printf("name:%s\n type:%s\n rating:%d\n releaseDate:%d\n",searchRslt->name,searchRslt->type,searchRslt->rating,searchRslt->releaseDate);
}
break;
case 2:
qsort(movieList,noOfReviews,sizeof(struct movie),nameStrCmp);
display(movieList,noOfReviews);
break;
case 3:
qsort(movieList,noOfReviews,sizeof(struct movie),ratingStrCmp);
display(movieList,noOfReviews);
break;
default:
break;
}
}
}
【问题讨论】:
-
您的
LIMIT是999,但缓冲区是100。那你fgets(buffer,LIMIT,fp);... -
你为什么要对
fgets撒谎?你告诉它你发送的缓冲区是 999 个字符宽,然后给它一个比那个小 899 个字符的缓冲区。而且您可以访问编译器而不是调试器?如果没有后者,您应该认为前者毫无意义。 -
检查文件是否正确打开:
FILE *fp = fopen(argv[1],"r"); if(!fp){ printf("cant open file\n"); } -
所以 LIMIT 也应该是 100?
-
当然,否则大小为 100 的缓冲区如何存储 999 个东西?这就像试图将 50 个人装进一辆出租车。无论如何,要找出导致问题的代码行,请在您认为可能导致问题的每一行之前和之后放置一个 printf 并查看输出是否显示在命令行中。如果第一个是,第二个不是,那么你找到了责任人。
标签: c file segmentation-fault malloc