2016-03-30 14 views
1

Ich habe in letzter Zeit an einem RPG in C-Sprache gearbeitet, und ich bin über einige Schwierigkeiten zum Speichern/Laden von Daten aus einer Textdatei gekommen.String zurückgegeben von C-Funktion ist Müll

Hier die ist (vereinfacht es kurz zu machen) Code:

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

struct player{ 
    int id; 
    char* name; 
}; 

void save(struct player* player) 
{ 
    FILE* fp = 0; 
    char* buffer = 0; 

    fp = fopen("./gamesave.txt", "w"); 
    fclose(fp); 
    buffer = malloc(80); 
    memset(buffer, 0, 80); 

    snprintf(buffer, 80, "%d|%s|\n", player->id, player->name); 
    fp = fopen("./gamesave.txt", "a"); 
    fputs(buffer, fp); 
    free(buffer); 
    fclose(fp); 
} 

struct player* load() 
{ 
    FILE* fp = 0; 
    char* buffer = 0; 
    struct player* player = malloc(sizeof(struct player)); 
    char tokens[] = "|\n"; 

    buffer = malloc (80); 
    memset(buffer, 0, 80); 

    fp = fopen("./gamesave.txt", "r"); 

    if (fgets(buffer, 80, fp)) { 
     char temp[20]; 
     player->id = atoi(strtok(buffer, tokens)); 
     strcpy(temp, strtok(NULL, tokens)); 
     player->name = temp; 
     printf("during load : name is %s\n", player->name); 
    } 
    fclose(fp); 
    free(buffer); 
    return player; 
} 

void main() 
{ 


    struct player* player = malloc(sizeof(struct player)); 
    player->id = 5; 
    player->name = "Bobby"; 
    printf("before save : my name is %s and id is %d\n", player->name, player->id); 

    save(player); 
    struct player* playerN = load(); 
    printf("after load : name is %s and id is %d", playerN->name, playerN->id); 
} 

Dies ist mein letzter Versuch dies zu tun, aber ich habe es viele differents versucht, Wege zu tun, aber es endet fast immer in dem Das gleiche Problem: Ich kann nicht die richtigen Werte für Strings bekommen, obwohl es für Integers funktioniert. Ich kann den Namen des Players vor speichern, während der Ladefunktion drucken, aber nach dem Laden druckt es nur Müll (die ID funktioniert gut).

Meine Vermutung ist, dass es mit einer Art von Speicherproblem zu tun hat, aber das ist es, konnte es nach Stunden und Stunden nicht lösen.

Vielen Dank im Voraus.

+0

Obwohl dies nicht mit Ihrem Gesamtproblem helfen wird, gibt es eine Verknüpfung, die Sie beim Speichern der Daten des Players machen können. Anstatt einen Puffer zuzuweisen und 'snprintf' zu verwenden, um in den Puffer zu schreiben und dann den Puffer in eine Datei zu schreiben, verwenden Sie stattdessen' fprintf' direkt, dann müssen Sie keinen Puffer reservieren. – dreamlax

+0

Sie sollten keinen Zeiger auf ein temporäres speichern. Außerdem sollten Sie entscheiden, welcher 'player-> name 'sein soll und bleiben Sie dabei. Wird es ein Zeiger auf eine String-Konstante sein? Ein Zeiger auf einen dynamisch zugewiesenen Puffer? Oder was? –

Antwort

2

Sie müssen Platz für player->name reservieren.

Sie verwenden dafür die automatische Variable temp, und ihre Lebensdauer endet, wenn die Funktion zurückkehrt. Auto-Variablen sind auf dem Stapel.

Sie nehmen also eine Adresse auf dem Stapel und halten es als Ihr Objekt. Dadurch wird ein Zeiger auf Ihre aktuelle Stapelebene verloren, da Sie sie zurückgeben. Es ist in Ordnung, Zeiger auf automatische Variablen zu verwenden, aber nur während diese Funktionsinstanz aktiv ist, d.h. in ihrem Lebenszyklus und in Funktionen, die sie aufruft.

+0

Hey, danke für deine Antwort, es hat mein Problem gelöst, indem ich 'char * temp = malloc (sizeof (char) * 20) geschrieben habe; 'stattdessen. Ich bin mir nicht sicher, ob ich den Grund, warum Sie dahinter steckten (noch nie von automatischen Variablen gehört), verstanden habe, aber ich werde morgen daran arbeiten. – Xely

+0

Schauen Sie sich die * Speicherklassen * für C-Objekte an. Es gibt Deklarationen, die statische Objekte erzeugen, die für immer leben, und "automatisch" und "register" Speicherklassen (für jetzt dieselben), die nur existieren, während die Funktionsaufrufinstanz aktiv ist. Der Stapel ist ein wichtiges Konzept und es ist der Mechanismus, auf dem jede signifikante Implementierung von C die (lokalen) Autoobjekte gründet. 'auto' ist der Standardwert für lokale Variablen. Viel Glück. – DigitalRoss

Verwandte Themen