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

使用!feof()读取Unicode文件时while循环无法终止的技术问题

解决while循环读取Unicode文件无法终止的问题

嘿,我来帮你拆解这个循环停不下来的问题,主要有三个核心错误导致了这个情况:

1. 循环条件逻辑完全搞反了

你写的while (c != Delim || !feof(f))用了逻辑或(||),这意味着只要满足其中一个条件就会继续循环——哪怕已经到了文件末尾(EOF),只要当前字符不是分隔符,循环就会一直跑。正确的逻辑应该是逻辑与(&&):只有当当前字符不是分隔符并且还没到文件末尾的时候,才继续循环。不过更严谨的写法是先判断读取是否成功,再做后续处理。

2. fgetwc的返回值类型误用

fgetwc的返回值是wint_t类型,而不是wchar_t。因为EOF是一个int类型的常量(值通常为-1),如果用wchar_t来接收,当fgetwc返回EOF时,会被转换成无符号的宽字符值,这个值永远不会等于你预期的EOF,导致feof(f)的判断完全失效。

3. 循环体内没有读取下一个字符

你只在循环开始前读取了一次字符,循环体里没有更新c的值,导致程序一直拿着同一个字符判断,永远跳不出循环。

修正后的代码示例

wchar_t* Getline(const wchar_t* Filename, const wchar_t Delim) {
    FILE* f = _wfopen(Filename, L"r, ccs=UTF-8");
    if (!f) { // 先检查文件是否打开成功
        wprintf(L"Failed to open file\n");
        return NULL;
    }

    wchar_t* info = NULL;
    wchar_t* temp = NULL;
    size_t count = 0; // 用size_t更适合计数
    wint_t c; // 改用wint_t接收fgetwc的返回值

    // 先读取字符,同时判断是否读取成功且未遇到分隔符
    while ((c = fgetwc(f)) != WEOF && c != Delim) {
        count++;
        // 重新分配内存,多留一个位置存字符串终止符
        temp = (wchar_t*)realloc(info, (count + 1) * sizeof(wchar_t));
        if (!temp) {
            free(info);
            wprintf(L"Failed to allocate memory\n");
            fclose(f); // 记得关闭文件避免泄漏
            return NULL;
        }
        info = temp;
        info[count - 1] = (wchar_t)c;
    }

    // 最后添加宽字符串终止符,确保返回合法的C风格字符串
    if (info) {
        temp = (wchar_t*)realloc(info, (count + 1) * sizeof(wchar_t));
        if (temp) {
            info = temp;
            info[count] = L'\0';
        }
    }

    fclose(f);
    return info;
}

额外优化点

  • 增加了文件打开失败的判断,避免后续操作空指针
  • 用size_t代替int计数,更符合C语言内存大小的类型规范
  • 手动添加宽字符串终止符L'\0',确保返回值是合法的宽字符串
  • 所有分支都关闭文件,避免资源泄漏

内容的提问来源于stack exchange,提问作者Huỳnh Lương Phương Trúc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:47:36