c - 如何修复使用 strtok 后打印的乱码
问题描述
我有 uni 项目,我需要检查语法是否正确。我得到一个指向字符串的指针,并检查第一个标记是否可以接受。万一没问题,我就往前走。但万一它不正常,我需要打印什么是错的。
我所做的是创建一个缓冲区,因为我无法更改原始字符串。之后我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',但它会打印:
You here, value str is sz<▒R
解决方案
char buf = NULL;
这是一个类型错误。buf
是单个字符,但是NULL
是指针值。您不能将指针存储在char
.
strcpy(&buf,str);
此代码具有未定义的行为(除非str
碰巧是空字符串)。buf
不是缓冲区,它是一个单一的char
,所以它没有空间来存储整个字符串。
如果要复制字符串,则需要为其所有字符分配足够的内存:
您可以使用
strdup
(在 POSIX 中,但不是标准 C):char *buf = strdup(str); if (!buf) { ... handle error ... } ... free(buf);
strdup
您可以手动复制:char *buf = malloc(strlen(str) + 1); if (!buf) { ... handle error ... } strcpy(buf, str); ... free(buf);
您可以使用可变长度数组(但您受到堆栈大小的限制,您无法检查错误):
char buf[strlen(str) + 1]; strcpy(buf, str); ...
推荐阅读
- ios - CoreML:有时会出现“意外错误处理模型”错误
- wordpress - 为什么缺少附件显示设置?
- java - Spring Boot - PostgreSQL 驱动程序不能位于类路径中
- java - 如何将 Cucumber 功能文件中的场景名称作为 Cucumber 步骤中的参数传递?
- linux - Makefile 无法识别已生成的源
- finite-automata - JFLAP 上的确定性有限自动机
- javascript - 展平嵌套的对象数组,将父值附加到子值
- java - java.sql.SQLException:字段“register_id”没有默认值
- python - 用python画决策树
- jqgrid - jqGrid filtertoolbar 隐藏在具有组标题和 Col Span 的冻结列上