我的C程序在输入后出现段错误,但我不确定该在哪里。该程序假定为电影列表动态分配内存,并能够添加和搜索列表。我不确定这有什么问题,我认为这与我的缓冲区有关。
程序接受movie.txt文件内容的命令行参数:
5 不可能完成的任务 行动 4 2008年 上 行动 3 2012
用户输入电影名称以按名称或等级搜索或显示电影
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// limit definition
#define LIMIT 100
//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");
if(!fp){
printf("cant open file\n");
}
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;
}
}
}
答案 0 :(得分:1)
在代码的不同地方,缓冲区可能在不同地方发生溢出。您的代码中充满了具有硬编码大小的数组,并且通常不清楚所有访问这些数组的代码是否都遵守大小限制。尽量避免使用具有硬编码大小的数组,而是动态分配它们。而且,如果您真的想在某些地方使用硬编码的数组大小,请使用某种“大小”常量,并尝试通过在代码中使用简洁的结构(例如写入“名称”的函数)来确保遵守该常量,超过名称大小等。
当“类型”的输入行长于29个字符(包括行终止)时,很容易使程序崩溃。这是因为使用buffer
将读取行newNode->type
(最多可以包含99个字符)复制到strcpy
(最多可以包含29个字符)中,这可能会超出缓冲区的末尾(缓冲区溢出)。
使程序崩溃的另一种方法是将超过1000条电影记录传递给它。