fgetwc EOF循环测试失败,但65535确定 [英] fgetwc EOF loop test fails, but 65535 OK

查看:298
本文介绍了fgetwc EOF循环测试失败,但65535确定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

VS10& MCBS:

VS10 & MCBS:

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

For this I have created a file called c:\eoftest containing the text "test". The value of ch on the 5th pass in the following code is 65535 returned by fgetwc, but it does not equate to EOF, which we all know is defined in stdio.h as (-1):

#include <stdio.h>
#include <windows.h>

int main()
{
    int ch;
    FILE *stream = NULL;
    wchar_t buf[5];
    memset (buf, '\0', sizeof(buf));
    stream = _wfopen(L"C:\\eoftest.txt", L"r");

            for (int i = 0; (i  < (sizeof(buf) - 1) && ((ch = fgetwc(stream)) != EOF) && (ch != '\0')); i++) //we are reading so last null condition mandatory
            {
            ungetwc(ch, stream);
            buf[i] = (wchar_t)(ch = fgetwc(stream));
            }
}

更换条件c>(ch = fgetwc(stream))!= 65535)在这种情况下工作,但是没有做什么来确保EOF测试可以成功?

Replacing the condition (sic) with (ch = fgetwc(stream)) != 65535) works in this case, but what is not done to ensure the EOF test can succeed?

推荐答案

从MSDN文档 fgetc ,fgetwc


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

fgetc returns the character read as an int or returns EOF to indicate an error or end of file. fgetwc returns, as a wint_t, the wide character that corresponds to the character read or returns WEOF to indicate an error or end of file.

WEOF 定义为 0xFFFF 这是你之前取代的 65535

WEOF is defined as 0xFFFF which is what you substituted earlier 65535

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

所以 EOF 测试宽字符应改为

if ((ch = fgetwc(stream)) != WEOF) ...






编辑


Edit

int main()
{
    wchar_t buf[5];
    memset(buf, '\0', 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 file\n");
            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 = %s\n", buf);

    return 0;
}






将逐行打印unicode文件的内容:


Edit 2: This will print content of unicode file line by line:

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'\0';

            //trim the '\r' at the end, if any
            if (i > 0 && buf[i - 1] == '\r') buf[i - 1] = L'\0';

            wprintf(L"%3d %s\n", ++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;
}

这篇关于fgetwc EOF循环测试失败,但65535确定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆