ファイルを開き、その内容を文字列バッファーに配置して、文字ごとに字句解析を行っています。このようにすると、後続の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;
}
これは常に完全にうまく機能しているように見えます。これに続くのは単純なループで、次のように文字列バッファの内容を一度に 1 文字ずつチェックします。
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 よりも高い値になるまでループが続きます。これは、適切な語彙分析には望ましくありません。これは、末尾の改行文字を省略したストリームで最終トークンをスキップすることがよくあるためです。
Basic Latin 文字セットでは、EOF char が負の値を持つ任意の文字であると想定しても安全でしょうか? それとも、これを行うためのより良い方法がありますか?
#EDIT: feof()関数をループに実装しようとしましたが、EOF も検出されないようです。