如何解决使用strtok
我有一个结构,其中包含我想从数组中填充的指针,这两个都在下面定义。我正在使用strtok在elements
数组中拆分字符串,然后获取各个值并将其放入相关的结构值中。
我可以将字符串ok拆分,但是填充到eleNum
中的值是错误的。我似乎正在获得一个指针值或类似的东西。我也不确定3个字段(eleNum,eleSym,eleName
)的内存分配是否正确。它们适用于eleSym
和eleName
,但我不知道这是运气还是为它们分配空间的正确方法。
typedef struct PTdef {
int *eleNum;
char *eleSym;
char *eleName;
} ptDB;
int main(void)
{
ptDB pt[118] = {};
char elements[][40] = {"1,H,Hydrogen"};
char *token;
char *eleDup = (char *)malloc(40);
char sep[] = ",";
strcpy(eleDup,elements[0]);
token = strtok(eleDup,sep);
pt[0].eleNum = malloc(sizeof(int));
pt[0].eleSym = (char *)malloc(sizeof(token));
pt[0].eleName = (char *)malloc(strlen(token));
pt[0].eleNum = (int *)token;
token = strtok(NULL,sep);
strcpy(pt[0].eleSym,token);
token = strtok(NULL,sep);
strcpy(pt[0].eleName,token);
输出应该是
pt[0].eleNum = 1.
pt[0].eleSym = H.
pt[0].eleName = Hydrogen.
解决方法
发布的代码有几个问题,请参见下面的内联注释。
typedef struct PTdef { int *eleNum; char *eleSym; char *eleName; } ptDB; int main(void) { ptDB pt[118] = {}; char elements[][40] = {"1,H,Hydrogen"}; char *token; char *eleDup = (char *)malloc(40); // no need to cast the return of malloc // https://stackoverflow.com/questions/605845/ char sep[] = ","; strcpy(eleDup,elements[0]); token = strtok(eleDup,sep); // now 'token' points to nul-terminated "1" pt[0].eleNum = malloc(sizeof(int)); // 'eleNum' points to a newly allocated int pt[0].eleSym = (char *)malloc(sizeof(token)); // allocates sizeof(char*) bytes // typically 4 bytes in 32-bit // or 8 bytes in 64-bit compiles // regardless of contents of 'token' pt[0].eleName = (char *)malloc(strlen(token)); // allocates strlen("1") = 1 byte pt[0].eleNum = (int *)token; // discards the previous value of the pointer // so it leaks the malloc(sizeof(int)) memory // and forces 'eleNum' to point to string "1" // which is not an 'int' token = strtok(NULL,sep); // now 'token' points to "H" strcpy(pt[0].eleSym,token); // copies nul-terminated "H" // to oversized 4- or 8-byte buffer token = strtok(NULL,sep); // now 'token' points to "Hydrogen" strcpy(pt[0].eleName,token); // copies nul-terminated "Hydrogen" // to 1-byte buffer,which overruns it
将其尽可能地靠近原始内容,以下代码将正常工作。
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct PTdef {
int eleNum; // store value,not pointer
char *eleSym;
char *eleName;
} ptDB;
int main()
{
ptDB pt[118] = {};
char elements[][40] = {"1,Hydrogen"};
char *token;
char eleDup[40]; // no need for dynamic allocation here
char sep[] = ",sep);
pt[0].eleNum = atoi(token); // convert string "1" to integer 1
token = strtok(NULL,sep);
pt[0].eleSym = strdup(token); // or: pt[0].eleSym = malloc(strlen(token) + 1);
// strcpy(pt[0].eleSym,token);
token = strtok(NULL,sep);
pt[0].eleName = strdup(token);
printf("num %d,sym '%s',name '%s'\n",pt[0].eleNum,pt[0].eleSym,pt[0].eleName);
free(pt[0].eleName); // cleanup
free(pt[0].eleSym);
return 0;
}
OP的左侧:
-
应该检查
-
strdup
的返回值以捕获内存不足的情况;
应该检查 -
strtok
返回值以捕获格式错误的字符串; -
atoi
不报告错误,请参见Why shouldn't I use atoi()?并使用strtol。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。