在C程序中输入后继续出现段错误

时间:2018-12-10 19:58:07

标签: c file segmentation-fault

我的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;
}
}
}

1 个答案:

答案 0 :(得分:1)

在代码的不同地方,缓冲区可能在不同地方发生溢出。您的代码中充满了具有硬编码大小的数组,并且通常不清楚所有访问这些数组的代码是否都遵守大小限制。尽量避免使用具有硬编码大小的数组,而是动态分配它们。而且,如果您真的想在某些地方使用硬编码的数组大小,请使用某种“大小”常量,并尝试通过在代码中使用简洁的结构(例如写入“名称”的函数)来确保遵守该常量,超过名称大小等。

当“类型”的输入行长于29个字符(包括行终止)时,很容易使程序崩溃。这是因为使用buffer将读取行newNode->type(最多可以包含99个字符)复制到strcpy(最多可以包含29个字符)中,这可能会超出缓冲区的末尾(缓冲区溢出)。

使程序崩溃的另一种方法是将超过1000条电影记录传递给它。