You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

wcstok触发Segmentation Fault:处理西里尔文本时程序崩溃求助

解决wcstok触发Segmentation Fault的问题

错误原因

  1. wcstok参数使用不当:wcstok的第三个参数要求传入指向wchar_t*的指针,用于存储解析过程的内部状态。你每次调用都传NULL,这种依赖函数内部静态变量的用法不仅线程不安全,在输入为空等场景下会触发未定义行为——从gdb信息看,save_ptr=0x0就是直接原因,函数尝试访问空指针导致段错误。
  2. 未处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:27:19