【问题标题】:Segmentation Error in C while trying to input尝试输入时C中的分段错误
【发布时间】: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;
}
}
}

【问题讨论】:

  • 您的LIMIT999,但缓冲区是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


【解决方案1】:

一些格式/可读性/编码建议:(有些只是建议,有些实际上消除了警告。)

  • 格式。 (主要是缩进)
  • 到处都用 MOVIE 替换 'struct movie'。 (参见下面的结构定义)
  • 使用前初始化变量。
  • 在声明和使用中注意缓冲区大小(fgets 错误)
  • 编译时打开警告。 (例如,使用 gcc use -Wall

以下内容仅限于解决这些项目中的每一项,包括新的结构定义。以下编译和构建没有警告或错误。它不包括调试您的代码。 (如果可以Beyond Compare (its free),在您的原始帖子和下面的编辑版本之间,您可以轻松找到编辑的位置。)

(在发这篇文章时,没有提供有关您的输入文件的信息,因此没有做出进一步的努力。)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// limit definition
#define LIMIT 999

//movie structure
typedef struct {
    char name[100];
    char type[30];
    int rating;
    int releaseDate;
}MOVIE;

//reads file
void readFile(FILE *fp,MOVIE* movieList[],int *noOfReviews)
{
    char buffer[LIMIT];
    int counter = 0;
    MOVIE* newNode = {0};
    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)
        {
            MOVIE* tmpNode = (MOVIE *)malloc(sizeof(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(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(((MOVIE*)a)->name,((MOVIE*)b)->name));
}
// compares rating strings
int ratingStrCmp(const void * a, const void * b)
{
    return (((MOVIE*)a)->rating - ((MOVIE*)b)->rating);
}
//displays the structure
void display(MOVIE* movieList[],int n)
{
    int i;
    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[])
{
    int noOfReviews;
    MOVIE* movieList[1000];
    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(MOVIE),nameStrCmp);
                display(movieList,noOfReviews);
                break;
            case 3:
                qsort(movieList,noOfReviews,sizeof(MOVIE),ratingStrCmp);
                display(movieList,noOfReviews);
                break;
            default:
                break;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 2017-02-14
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多