C中推箱子游戏的加载程序分段错误

时间:2019-03-01 12:31:55

标签: c file

所以我试图用C语言编写一个代码,该代码将从文件中创建一个字符数组,如下所示:

10 8
##########
######  ##
# $  $  ##
# #  .# ##
#  . #.@ #
##$# *   #
##   #####
##########

但是我遇到了分段错误,我一直在寻找错误的根源……如果有人可以阅读我的代码并给我他/她的反馈,我将不胜感激。 预先感谢!

//We define a structure representing a map (for the Sokoban game)
    typedef struct map map;
    struct map{
        int width;
        int height;
        int x;
        int y;// x and y are the position of the player
        char* p_char; //p_char is pointing an array which will contain the elements of the map, the characters currently on the file above
    };

    //The function that reads the file and store the characters in an array
    char* ReadMap(const char const* filename)
    {
        FILE* p_file = fopen(filename, "r");
        char* p_array = NULL;
        if (p_file = NULL) {
            exit(EXIT_FAILURE);
        }
        else{   
            size_t size=1;
            while (getc(p_file)!=EOF) {
                size++;
            }
            p_array=(char*)malloc(sizeof(char)*size);
            fseek(p_file,0,SEEK_SET);
            for(size_t i=3; i<size-1; i++) {
                p_array[i]=(char)getc(p_file);//i=3 cause we don't want the 2 first int, representing the size of the array
            }
            p_array[size-1]='\0';
            fclose(p_file);
        }
        return p_array;
    }

    int main(int argc, char *argv[]){
        if (argc != 2) {
            fprintf(stderr, "You must provide a file name!\n");
            exit(EXIT_FAILURE);
        }
        //We define a map structure
        map map_loaded; 
        FILE *p_file1 = NULL;
        p_file1=fopen(argv[1],"r");
        if (p_file1==NULL) {
            fprintf(stderr, "Cannot read file %s!\n", argv[1]);
            exit(EXIT_FAILURE);
        }
        //we're trying to recover width and height, two int at the beginnning of the file
        int width=0;
            map_loaded.width=width;
        int height=0;
            map_loaded.height=height;
        int fscanf_result=0;
            fscanf_result=fscanf(p_file1, "%d %d\n", &width, &height);
        char* p_char=NULL;
        map_loaded.p_char=p_char;
        p_char=ReadMap(argv[1]);
        if (p_char != NULL) {
            printf("%s\n", p_char);
            free(p_char);
        }
    }

1 个答案:

答案 0 :(得分:1)

分段错误的原因是将表达式declare let window; 用作条件。

p_file = NULL assignment 表达式。它将p_file = NULL设置为p_file并求值为分配的值NULLNULL用作条件时被视为错误。

另一方面,条件为假表示条件为比较 NULL时文件打开成功。

在这种情况下,当p_file == NULL不是p_file时,条件变为假。

因此,编写了预期NULL不是p_file的代码 在NULL子句中。

代码中包含将else传递给p_file的语句。

结果,fgetc()被传递到NULL,这是分段错误的可能原因。

请注意,摆脱了细分错误后,您的代码仍然看起来有误。

在示例中,大小部分为fgetc(),长度为4个字符。这意味着跳过“ 3个字符”没有意义。

还请注意,10 8从3开始不会跳过文件内容,只是将数组的前3个元素保留为未初始化,这是某些程序员的观点。

相反,您可以“跳过第一行”。换句话说,您可以“跳到第一个换行符”。

i

启用size_t size=1; int c; while (getc(p_file)!=EOF) { size++; } fseek(p_file,0,SEEK_SET); while ((c=getc(p_file))!='\n' && c!=EOF) { // drop the first line size--; } p_array=(char*)malloc(sizeof(char)*size); if (p_array!=NULL) { // for in case malloc() fails for(size_t i=0; i<size-1; i++) { p_array[i]=(char)getc(p_file); } p_array[size-1]='\0'; } fclose(p_file); 索引的一种方法是通过在行width*i+j之后添加以下代码来删除换行符:

p_array[i]=(char)getc(p_file);