C - fscanf 错误与 char *
C - fscanf error with char *
我正在尝试读取此格式的 txt 文件:
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
列为:hp、宇宙颜色、宇宙编号和名称。我所做的是读取该行并将参数保存在一个名为 warrior 的结构数组中,格式如下:
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;
}
读取文件代码为:
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
第二次迭代打印:
j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Vegeta
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Vegeta
等等。
问题是您读取了名字,然后为文件中的每个战士设置了一个指向该名字的指针。对于文件中的每个元素,您必须为其名称分配新内存(使用 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;
}
还有另一种很酷的方法可以使用 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>
来自 scanf 的所有输入都写入了为 inName[50] 指定的同一内存位置。在每次迭代中,您都在覆盖内容,但将相同的地址分配给 guerrero.name。当您打印出来时,您会打印最后一个条目。
你可以试试这个:
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
...
guerrero.name = strdup(inName);
....
return guerrero;
}
我正在尝试读取此格式的 txt 文件:
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
列为:hp、宇宙颜色、宇宙编号和名称。我所做的是读取该行并将参数保存在一个名为 warrior 的结构数组中,格式如下:
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;
}
读取文件代码为:
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
第二次迭代打印:
j: 0 - HP: 8590 - Color: 2 - Universo: 7 - Nombre: Vegeta
j: 1 - HP: 8591 - Color: 2 - Universo: 7 - Nombre: Vegeta
等等。
问题是您读取了名字,然后为文件中的每个战士设置了一个指向该名字的指针。对于文件中的每个元素,您必须为其名称分配新内存(使用 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;
}
还有另一种很酷的方法可以使用 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>
来自 scanf 的所有输入都写入了为 inName[50] 指定的同一内存位置。在每次迭代中,您都在覆盖内容,但将相同的地址分配给 guerrero.name。当您打印出来时,您会打印最后一个条目。
你可以试试这个:
warrior createWarrior(int inHp, int inColor, int inUniverse, char * inName){
...
guerrero.name = strdup(inName);
....
return guerrero;
}