我正在打开一个文件并将其内容放入字符串缓冲区中,以对每个字符进行一些词法分析。这样做可以比使用后续的fread()调用更快地完成解析,并且由于源文件将始终不大于几 MB,因此我可以放心,将始终读取文件的全部内容.
但是,检测何时没有更多数据要解析似乎有些麻烦,因为ftell()经常给我一个整数值,该整数值高于文件中的实际字符数。如果尾随字符始终为 -1,则使用 EOF (-1) 宏不会有问题……但情况并非总是如此……
这是我打开文件并将其读入字符串缓冲区的方式:
FILE *fp = NULL;
errno_t err = _wfopen_s(&fp, m_sourceFile, L"rb, ccs=UNICODE");
if(fp == NULL || err != 0) return FALSE;
if(fseek(fp, 0, SEEK_END) != 0) {
fclose(fp);
fp = NULL;
return FALSE;
}
LONG fileSize = ftell(fp);
if(fileSize == -1L) {
fclose(fp);
fp = NULL;
return FALSE;
}
rewind(fp);
LPSTR s = new char[fileSize];
RtlZeroMemory(s, sizeof(char) * fileSize);
DWORD dwBytesRead = 0;
if(fread(s, sizeof(char), fileSize, fp) != fileSize) {
fclose(fp);
fp = NULL;
return FALSE;
}
这似乎总是工作得很好。下面是一个简单的循环,它一次检查一个字符的字符串缓冲区的内容,如下所示:
char c = 0;
LONG nPos = 0;
while(c != EOF && nPos <= fileSize)
{
c = s[nPos];
// do something with 'c' here...
nPos++;
}
文件的尾随字节通常是一系列ý (-3)和« (-85)字符,因此永远不会检测到 EOF。相反,循环只是继续前进,直到nPos最终具有比fileSize更高的值——这对于正确的词法分析来说是不可取的,因为您通常最终会跳过流中的最后一个标记,它在末尾省略了换行符。
在基本拉丁字符集中,假设 EOF 字符是具有负值的任何字符是否安全?或者也许有更好的方法来解决这个问题?
#EDIT:我刚刚尝试将feof()函数实现到我的循环中,但同样,它似乎也没有检测到 EOF。