2014-05-09 2 views
0

Когда я выполняю команду printf для описания уровня->, программа дает мне ошибку сегментации. Я не знаю почему. Должен ли я использовать malloc для его ремонта? Содержимое (только 1 строка, заканчивающаяся на «\ n») файла sokoban.dat, является «chicago; addie; история начинается здесь; ----- ##### ----------- | -----#@$.#-----------|-----#####----------- "Ошибка сегментации при подключении к структуре

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

typedef struct { 
char *name; 
char *description; 
char *password; 
char *map; 
struct level *next; 
//char *solution; 
} LEVEL; 

LEVEL* parse_level(char *line) { //parsing from file into the structure 
    LEVEL level; 
    char level_name[50]; 
    char level_password[50]; 
    char level_description[100]; 
    char level_map[200]; 

    int i = 0; 
    int j = 0; 
    while (line[i] != ';') {  //getting level name 
     level_name[j] = line[i]; 
     i++; 
     j++; 
    } 
    level_name[j]='\0'; 
    level.name=&level_name[0]; 
    //strcpy(&level.name,level_name); 
    //printf("%s\n",level.name); 
    printf("%s\n",level_name); 
    j = 0; 
    i++; 
    while (line[i] != ';') {  //getting level password 
     level_password[j] = line[i]; 
     i++; 
     j++; 
    } 
    level_password[j]='\0'; 
    level.password=&level_password[0]; 
    printf("%s\n",level_password); 
    j = 0; 
    i++; 
    while (line[i] != ';') {  //getting level description 
     level_description[j] = line[i]; 
     i++; 
     j++; 
    } 
    level_description[j]='\0'; 
    level.description=&level_description[0]; 
    printf("%s\n",level_description); 
    j = 0; 
    i++; 
    while (line[i] != '\n') { //getting level map 
     level_map[j] = line[i]; 
     i++; 
     j++; 
    } 
    level_map[j]='\0';   
    level.map=&level_map[0]; 
    printf("%s\n",level_map); 
    j = 0; 
    level.next=NULL;  
    LEVEL* levelPointer=&level; 
    return levelPointer; 
} 
int main(){ 
    FILE *fp = fopen("sokoban.dat", "r"); 
    if(fp == NULL){ 
     printf("No such file\n"); 
     return 1; 
    } 

    char line[500]; 
    //strcpy(line,""); 
    char c; 
    int i=0; 
    while((c = fgetc(fp)) != '\n'){ //reading from file 1 by 1 character 
     line[i]=c; 
     i++; 
    } 
    printf("%s\n",line); 
    LEVEL* level; 
    level=parse_level(line); 
    //printf("%s\n",level->description); **//!!! this is where error occur** 
    printf("%s\n",level->map); 

    return 0; 
} 
+1

Используйте отладчик, такой как gdb, чтобы найти, где именно находится ваш код, ваша проблема, или комментарии частей вашей программы, чтобы сузить недостатки. Как бы то ни было, другие пользователи StackOverflow вряд ли будут очень много работать, чтобы решить вашу проблему. –

+0

проблематичный - это пятая строка снизу (это когда происходит ошибка). Я использую NetBeans для отладки, а для переменной level-> description он дает мне адрес: 0x52 <Адрес 0x52 вне границ>. – Dounchan

+0

ОК, так есть там терминатор мулл? –

ответ

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

typedef struct level { 
    char *name; 
    char *description; 
    char *password; 
    char *map; 
    struct level *next; 
    //char *solution; 
} LEVEL; 

#if 0 
char *strdup(const char *str){ 
    size_t len = strlen(str); 
    char *ret = malloc(len + 1); 
    if(ret){ 
     memcpy(ret, str, len + 1); 
     //ret[len] = '\0'; 
    } 
    return ret; 
} 
#endif 

LEVEL* parse_level(char *line) { 
    //Returns the allocated memory 
    LEVEL *level = malloc(sizeof(LEVEL)); 
    char *token; 
    token=strtok(line, ";");//It cut the string as a separator the ';'. 
    level->name = strdup(token);//Copy the memory allocated strings cut out. 

    token=strtok(NULL, ";");//Get next token 
    level->password = strdup(token); 
    token=strtok(NULL, ";"); 
    level->description = strdup(token); 
    token=strtok(NULL, ";"); 
    level->map = strdup(token); 
    level->next = NULL; 
#if DEBUG 
    printf("debug print : level\n"); 
    printf("%s\n", level->name); 
    printf("%s\n", level->password); 
    printf("%s\n", level->description); 
    printf("%s\n", level->map); 
#endif 
    return level; 
} 
void LEVEL_free(LEVEL *p){ 
    free(p->name); 
    free(p->password); 
    free(p->description); 
    free(p->map); 
    free(p); 
} 

int main(){ 
    FILE *fp = fopen("sokoban.dat", "r"); 
    if(fp == NULL){ 
     printf("No such file\n"); 
     return 1; 
    } 

    char line[500]; 
    char c; 
    int i=0; 
    while((c = fgetc(fp)) != '\n'){ //reading from file 1 by 1 character 
     line[i]=c; 
     i++; 
    } 
    line[i] = '\0'; 
    printf("%s\n",line); 
    LEVEL* level; 
    level=parse_level(line); 
    printf("%s\n",level->description); 
    printf("%s\n",level->map); 

    LEVEL_free(level);//free for malloced memory 
    return 0; 
} 
+0

Спасибо большое! ..... Теперь я могу двигаться дальше. Я не знал о функции 'strtok()' На самом деле это необходимо? '#if 0 char * strdup (const char * str) { size_t len ​​= strlen (str); char * ret = malloc (len + 1); if (ret) { memcpy (ret, str, len + 1); // ret [len] = '\ 0'; } return ret; } # endif' – Dounchan

+0

@Dounchan; Я написал примерный «strdup», который не является стандартной функцией. Он не требуется, если он уже существует в вашей среде (в ). – BLUEPIXY

1

В функции parse_level() вы берете адреса всех локальных переменных и копируете в переменную structlevel и возвращаете level. Все эти копии локальных адресов и использование этих объектов позже после их срок службы делают вашу программу незаконной и вызывает undefined behaviour.

Прежде чем погрузиться в глубь, вы должны сначала прочитать об основах языка и понять понятия, такие как указатели, массивы, возвращающие значения из функции, возвращающие указатели и т. Д.

Те, связанные с вашими проблемами являются:

returning a local variable from function in C

Since I can't return a local variable, what's the best way to return a string from a C or C++ function?

Undefined, unspecified and implementation-defined behavior

Undefined behavior and sequence points

The Definitive C Book Guide and List

+0

Без сомнения, я должен учиться больше. Лучший метод - это обучение примерами. Я пройду через предоставленные вами ссылки В любом случае, книга Kernighan & Ritchie довольно трудно впитывать! – Dounchan

Смежные вопросы