C 如何修复使用strtok后打印的乱码
我有uni项目,我需要检查语法是否正确。我获取指向字符串的指针,并检查第一个标记是否可接受。如果没事的话,我继续前进。但万一不行,我需要打印出哪里出了问题 我所做的是创建一个缓冲区,因为我无法更改原始字符串。 之后,我使用C 如何修复使用strtok后打印的乱码,c,string,strtok,C,String,Strtok,我有uni项目,我需要检查语法是否正确。我获取指向字符串的指针,并检查第一个标记是否可接受。如果没事的话,我继续前进。但万一不行,我需要打印出哪里出了问题 我所做的是创建一个缓冲区,因为我无法更改原始字符串。 之后,我使用strtok剪切缓冲区,看看我得到的令牌是否可以接受 char *str = "sz = 12345"; printf("The check of MACRO: %d\n", isMacro(str)); int isMacro(char *str) { char b
strtok
剪切缓冲区,看看我得到的令牌是否可以接受
char *str = "sz = 12345";
printf("The check of MACRO: %d\n", isMacro(str));
int isMacro(char *str)
{
char buf = NULL;
char *token;
strcpy(&buf,str);
token = strtok(&buf," ");
printf("You here, value token is %s\n",token);
}
我希望printf
会打印'sz',但它会打印:
你在这里,str值是sz
这是一个类型错误buf
是单个字符,但NULL
是指针值。不能将指针存储在字符中
strcpy(&buf,str);
此代码具有未定义的行为(除非str
恰好是空字符串)buf
不是缓冲区,它是单个char
,因此它没有空间存储整个字符串
如果要复制字符串,需要为其所有字符分配足够的内存:
您可以使用strdup
(在POSIX中,但不是标准C):
您可以手动复制strdup
:
char *buf = malloc(strlen(str) + 1);
if (!buf) {
... handle error ...
}
strcpy(buf, str);
...
free(buf);
可以使用可变长度数组(但受堆栈大小限制,无法检查错误):
buf
是单个char
而不是指向char
的指针。事实上,如果您计划执行strcpy将字符串复制到它,那么首先需要使用malloc分配内存。相反,我建议您使用类似于strdup
的函数而不是strcpy
来创建原始字符串的副本,以便使用strtok对其进行修改。请记住以后释放字符串
像这样的
int isMacro(char *str)
{
char *buf = NULL;
char *token;
buf = strdup(str);
token = strtok(buf," ");
printf("You here, value of token is %s\n",token);
free(buf);
}
为什么char buf=NULL
甚至可以编译?@Ayxan在某些平台上NULL
被定义为0
,而不是((void*)0)
,因此代码实际上变成了buf='\0'
。其他编译器将(某些)类型错误视为可选警告,而不是硬错误。很好的建议,但值得注意的是,strdup
不是c标准库的一部分(它是POSIX),因此一些编译器可能不提供它(在这种情况下,您的strlen、malloc
和memcpy
建议很好)isMacro()
未命中返回值。isMacro()
未命中返回值,因此outprintf()
可能会调用未定义的行为。
char *buf = malloc(strlen(str) + 1);
if (!buf) {
... handle error ...
}
strcpy(buf, str);
...
free(buf);
char buf[strlen(str) + 1];
strcpy(buf, str);
...
int isMacro(char *str)
{
char *buf = NULL;
char *token;
buf = strdup(str);
token = strtok(buf," ");
printf("You here, value of token is %s\n",token);
free(buf);
}