fgetwc EOF 循环测试失败,但 65535 OK
fgetwc EOF loop test fails, but 65535 OK
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, '[=10=]', sizeof(buf));
stream = _wfopen(L"C:\eoftest.txt", L"r");
for (int i = 0; (i < (sizeof(buf) - 1) && ((ch = fgetwc(stream)) != EOF) && (ch != '[=10=]')); 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 文档
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
#define WEOF ((wint_t)(0xFFFF))
所以宽字符的 EOF
测试应该改为
if ((ch = fgetwc(stream)) != WEOF) ...
编辑
int main()
{
wchar_t buf[5];
memset(buf, '[=12=]', 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;
}
编辑 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'[=13=]';
//trim the '\r' at the end, if any
if (i > 0 && buf[i - 1] == '\r') buf[i - 1] = L'[=13=]';
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;
}
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, '[=10=]', sizeof(buf));
stream = _wfopen(L"C:\eoftest.txt", L"r");
for (int i = 0; (i < (sizeof(buf) - 1) && ((ch = fgetwc(stream)) != EOF) && (ch != '[=10=]')); i++) //we are reading so last null condition mandatory
{
ungetwc(ch, stream);
buf[i] = (wchar_t)(ch = fgetwc(stream));
}
}
用(ch = fgetwc(stream)) != 65535)
替换条件(原文如此)在这种情况下是可行的,但是没有做什么来确保EOF测试能够成功?
fgetc
returns the character read as anint
or returnsEOF
to indicate an error or end of file.fgetwc
returns, as awint_t
, the wide character that corresponds to the character read or returnsWEOF
to indicate an error or end of file.
WEOF
定义为 0xFFFF
,这是您之前替换的内容 65535
#define WEOF ((wint_t)(0xFFFF))
所以宽字符的 EOF
测试应该改为
if ((ch = fgetwc(stream)) != WEOF) ...
编辑
int main()
{
wchar_t buf[5];
memset(buf, '[=12=]', 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;
}
编辑 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'[=13=]';
//trim the '\r' at the end, if any
if (i > 0 && buf[i - 1] == '\r') buf[i - 1] = L'[=13=]';
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;
}