fgetwc EOF 循环测试失败,但 65535 正常

fgetwc EOF loop test fails, but 65535 OK

本文关键字:65535 正常 失败 EOF 循环测试 fgetwc      更新时间:2023-10-16

VS10 & MCBS:

为此,我创建了一个名为c:\eoftest的文件,其中包含文本"test"。在以下代码中,第 5 次传递的 ch 值是 fgetwc 返回的 65535,但它并不等同于 EOF,我们都知道 stdio.h 中将其定义为 (-1):

#include <stdio.h>
#include <windows.h>
int main()
{
    int ch;
    FILE *stream = NULL;
    wchar_t buf[5];
    memset (buf, '', sizeof(buf));
    stream = _wfopen(L"C:\eoftest.txt", L"r");
            for (int i = 0; (i  < (sizeof(buf) - 1) && ((ch = fgetwc(stream)) != EOF) && (ch != '')); i++) //we are reading so last null condition mandatory
            {
            ungetwc(ch, stream);
            buf[i] = (wchar_t)(ch = fgetwc(stream));
            }
}

在这种情况下,用(ch = fgetwc(stream)) != 65535)替换条件(原文如此)是有效的,但是没有采取什么措施来确保EOF测试可以成功?

来自 MSDN 文档 for fgetc, fgetwc

fgetc返回作为int读取的字符,或返回指示错误或文件结尾的字符EOF fgetwc返回,作为 wint_t ,对应于读取字符或 返回 WEOF 以指示错误或文件结束。

WEOF定义为您之前替换的0xFFFF 65535

#define WEOF ((wint_t)(0xFFFF))

因此,宽字符的EOF测试应更改为

if ((ch = fgetwc(stream)) != WEOF) ...
<小时 />

编辑

int main()
{
    wchar_t buf[5];
    memset(buf, '', sizeof(buf));
    wcscpy(buf, L"1234");
    FILE *stream = _wfopen(L"C:\eoftest.txt", L"rb");
    if (!stream)
    {
        stream = _wfopen(L"C:\eoftest.txt", L"w+b");
        if (!stream)
        {
            printf("cannot create filen");
            return 0;
        }
        fwrite((char*)buf, sizeof(buf[0]), wcslen(buf), stream);
        fseek(stream, 0, 0);
    }
    int len = sizeof(buf) / sizeof(buf[0]);
    for (int i = 0; i < len; i++) 
    {
        wchar_t ch = fgetwc(stream);
        if (ch == WEOF) break;
        buf[i] = ch;
    }
    wprintf(L"result = %sn", buf);
    return 0;
}
<小时 />

编辑2:这将逐行打印unicode文件的内容:

int main()
{
    FILE *stream = _wfopen(L"c:\test\test.txt", L"rb");
    if (!stream) return 0;
    int buflen = 256;
    wchar_t* buf = (wchar_t*)malloc(buflen * sizeof(wchar_t));
    if (fread(buf, 2, 1, stream))
    {
        if (buf[0] != 0xFEFF)
        {
            //BOM not detected, go back to start of file
            rewind(stream);
        }//else, skip the first 2 bytes
    }
    int i = 0, line = 0;
    wint_t ch = 0;
    while (ch != WEOF)
    {
        ch = fgetwc(stream);
        if (ch == L'n' || ch == WEOF)
        {
            //null-terminate the buffer at i
            buf[i] = L'';
            //trim the 'r' at the end, if any
            if (i > 0 && buf[i - 1] == 'r') buf[i - 1] = L'';
            wprintf(L"%3d %sn", ++line, buf);
            //start a new line for the next pass
            i = 0;
        }
        else
        {
            buf[i] = ch;
            i++;
            if (i == buflen)
            {
                //increase buffer:
                buflen += 256;
                buf = (wchar_t*)realloc(buf, buflen * sizeof(wchar_t));
            }
        }
    }
    free(buf);
    return 0;
}