wcstok触发Segmentation Fault:处理西里尔文本时程序崩溃求助
解决wcstok触发Segmentation Fault的问题
错误原因
- wcstok参数使用不当:wcstok的第三个参数要求传入指向
wchar_t*的指针,用于存储解析过程的内部状态。你每次调用都传NULL,这种依赖函数内部静态变量的用法不仅线程不安全,在输入为空等场景下会触发未定义行为——从gdb信息看,save_ptr=0x0就是直接原因,函数尝试访问空指针导致段错误。 - 未处理fgetws异常情况:如果fgetws读取失败(比如无输入、读取出错),
sentence数组内容是未初始化的垃圾值,此时调用wcstok必然引发内存访问错误。
修复后的代码
#include <stdio.h> #include <wchar.h> #include <wctype.h> int main() { wchar_t sentence[201]; // 检查fgetws返回值,处理读取失败的情况 if (fgetws(sentence, 201, stdin) == NULL) { fwprintf(stderr, L"读取输入失败\n"); return 1; } // 去除fgetws读取的换行符(可选但推荐) wchar_t *newline = wcschr(sentence, L'\n'); if (newline != NULL) { *newline = L'\0'; } wchar_t delimiters[] = L" ,-"; wchar_t *save_ptr; // 用于保存wcstok的内部状态 wchar_t *word = wcstok(sentence, delimiters, &save_ptr); while (word != NULL) { wprintf(L"%ls\n", word); // 加换行符实现逐行输出 word = wcstok(NULL, delimiters, &save_ptr); } return 0; }
关键修改点
- 新增
save_ptr变量,每次调用wcstok时传入它的地址,替代原来的NULL,确保函数能正确维护解析状态,避免空指针访问。 - 检查fgetws返回值,提前处理读取失败的情况,避免操作未初始化的内存。
- 调用
wcschr去除换行符:fgetws会把输入的换行符读入数组,去除后输出更符合逐行拆分的预期。 - 输出时添加
\n,满足逐行输出的需求。
内容的提问来源于stack exchange,提问作者unndere
相关产品推荐
相关产品推荐

