使用strtok
时遇到问题,我不知道问题是在strtok
还是其他问题上。
我有一个包含以下数据的.txt文件:
sometextdada;othertextdata
yetmoredata;andmoredata
读取数据将以struct
的方式存储:
typedef struct team{
char *name;
char *teamPlace;
}Team;
如果我这样做:
char buffer[100];
Team eq;
/*Read first line*/
fgets(buffer, 100, equipas)!= NULL);
eq.name= strtok(buffer,";\n");
eq.teamPlace= strtok (NULL,";\n");
printf("%s %s\n", eq.name,eq.teamPlace);
我可以看到strtok
按预期工作,并在sometextdada
和eq.name
othertextdata
中存储eq.teamPlace
现在我想将printf
替换为将eq
添加到以这种方式定义的链接列表的函数:
typedef struct nodeTeam{
int numberOfTeams;
Team team;
struct nodeTeam *next;
struct nodeTeam *prev;
}NodeTeam;
所以我将printf
替换为addNodeTeamsSorted(headEquipas,&tailEquipas,eq);
fgets(buffer, 100, equipas)!= NULL);
eq.name= strtok(buffer,";\n");
eq.teamPlace= strtok (NULL,";\n");
addNodeTeamsSorted(headEquipas,&tailEquipas,eq);
现在,如果我打印链表,我可以看到我的节点已添加,但name
和teamPlace
包含垃圾字符。但如果我这样做:
fgets(buffer, 100, equipas)!= NULL);
eq.name= "test";
eq.teamPlace= "test2";
addNodeTeamsSorted(headEquipas,&tailEquipas,eq);
我可以看到所有内容都按预期工作,这让我觉得问题出现在我的char
上的struct
字符串
我做错了什么?
答案 0 :(得分:2)
strtok
对您在the first call中指定的缓冲区进行操作。不是直接存储返回的指针(指向每个行处理中覆盖的buffer
),而是需要复制字符串(例如strncpy()
)
答案 1 :(得分:2)
你的问题是你的缓冲区是在堆栈上创建的,而strtok的结果是指向缓冲区。
当您从此函数返回或从缓冲区中读取另一行时,堆栈(以及您的缓冲区)将被重用于其他内容,并且指针指向的数据已被覆盖。常量字符串不会发生这种情况,因为它们位于静态内存区域而不是堆栈中。
尝试在strtok()的输出上使用函数strdup()并将它们保存到您的结构中;这会将strtok()返回的字符串复制到堆中,在那里它们不会被意外覆盖。