2017-06-07 7 views
2

私はこの形式でTXTファイルを読み込むしようとしているとfscanfはエラー:C - のchar *

8590 2 07 Goku 
8591 2 07 Vegeta 
6973 2 07 Picolo 
5432 3 02 Jerez 
6773 3 02 Sour 
4689 4 03 Mosco 
6981 5 06 Cabba 
7891 5 06 Frost 

列は次のとおりです。馬力、宇宙の色、宇宙の番号と名前。

typedef struct Warrior{ 
    int hp; 
    int color; 
    int universe; 
    char * name; 
    int posX; 
    int posY; 
    int ki; 
} warrior; 

warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){ 
    warrior guerrero; 
    guerrero.hp = inHp; 
    guerrero.color = inColor; 
    guerrero.universe = inUniverse; 
    guerrero.name = inName; 
    guerrero.posX= 0; 
    guerrero.posY= 0; 
    guerrero.ki=0; 
    return guerrero; 
} 

readFileのコードは次のとおりです:私は何をすることは、これはラインを読み、このフォーマットを持つ戦士と呼ばれる構造体の配列のパラメータを保存している

warrior * readFile(char * nameFile, warrior * listGuerrero){ 
    FILE * filePointer; 
    int sizeFile = 0, ch = 0; 
    int inHp, inColor, inUniverse; 
    char inName[50]; 

    filePointer = fopen(nameFile, "r"); 

    while(fscanf(filePointer, "%d %d %d %s\n", &inHp, &inColor, &inUniverse, inName) != EOF){ 
     sizeFile ++; 
    } 

    rewind(filePointer); 

    listGuerrero = (warrior *)malloc(sizeFile*sizeof(warrior)); 
    for(int k = 0; k < sizeFile; k++){ 
     fscanf(filePointer, "%d %d %d %s\n", &inHp, &inColor, &inUniverse, &inName[0]); 
     listGuerrero[k] = createWarrior(inHp,inColor,inUniverse,inName); 
     printf("k: %d - HP: %d - Color: %d - Universo: %d - Nombre: %s \n", k, listGuerrero[k].hp, listGuerrero[k].color, listGuerrero[k].universe, listGuerrero[k].name); 
    } 

    fclose(filePointer); 
    return listGuerrero; 
} 

が、何らかの理由で私はできません

j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Frost 
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Frost 
j: 2 - HP: 6973 - Color: 2 - Universo: 7 - Nombre: Frost 
j: 3 - HP: 5432 - Color: 3 - Universo: 2 - Nombre: Frost 
j: 4 - HP: 6773 - Color: 3 - Universo: 2 - Nombre: Frost 
j: 5 - HP: 4689 - Color: 4 - Universo: 3 - Nombre: Frost 
j: 6 - HP: 6981 - Color: 5 - Universo: 6 - Nombre: Frost 
j: 7 - HP: 7891 - Color: 5 - Universo: 6 - Nombre: Frost 

inNameポインタがおかしいです:理解し、戦士の最終的なリストはすべてのように同じ名前を持っていますか?

私は、最初の反復プリントデバッグ:

j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Goku 

そして、第2の反復プリント:

j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Vegeta 
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Vegeta 

などを。

+0

注意を。名前を別々に保存しなかったためです。スペースを割り当てて名前のコピーを作るのではなく、 'inName'へのポインタを構造体にコピーするだけです。 'inName'はread関数のローカル変数なので、後でなく早く名前が壊れることもあります。構造体の名前も 'char *'であることは明らかですが、構造体の定義も表示するべきです。 –

答えて

2

問題は、あなたがファーストネームを読んでいて、ファイル内のすべての戦士のためにそのファーストネームへのポインタを設定しているということです。ファイルの各要素について、その名前(mallocを使用)に新しいメモリを割り当て、新しい名前をstrcpyを使ってコピーする必要があります。名前はchar *

warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){ 

    warrior guerrero; 
    guerrero.hp = inHp; 
    guerrero.color = inColor; 
    guerrero.universe = inUniverse; 

    guerrero.name = malloc(sizeof(char) * 30); // 30 is the length of the name 

    strcpy(guerrero.name,inName); // copy new name 
    guerrero.posX= 0; 
    guerrero.posY= 0; 
    guerrero.ki=0; 

    return guerrero; 

} 

基本的に新しいメモリをalocatesのstrdup()を使用して、それを行うと、そこにパラメータ文字列をコピーする別のクールな方法があると宣言しているので(しかし、私はこれをテストしていませんでした):

warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){ 

    warrior guerrero; 
    guerrero.hp = inHp; 
    guerrero.color = inColor; 
    guerrero.universe = inUniverse; 

    guerrero.name = strdup(inName); 
    guerrero.posX= 0; 
    guerrero.posY= 0; 
    guerrero.ki=0; 

    return guerrero; 

} 
は忘れないでください:

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

ありがとう、これは働いた!! –

1

scanf関数からご入力のすべてがinName [50]のために与えられた同じメモリ位置に書き込まれます。各反復では、コンテンツを上書きしますが、guerrero.nameに同じアドレスを割り当てます。そしてあなたがプリントアウトすると、あなたは最後のエントリーをプリントします。

あなたはこの試みることがあります。それが保存される読み取られる姓だと

warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){ 
... 
guerrero.name = strdup(inName); 
.... 
return guerrero; 
}