次のCコードはstdin
からfgetws()
を使用して行を読み取り、stdout
に書き込みます。fgetws()とUTF-8を使用したEILSEQ
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#define STR_LEN 128
int main(int argc, char **argv)
{
FILE *infile = stdin, *outfile = stdout;
wchar_t str[STR_LEN];
if (setlocale(LC_ALL, "en.UTF-8") == NULL) {
fprintf(stderr, "Cannot set locale\n");
return 1;
}
for (;;) {
if (!fgetws(str, STR_LEN, infile)) {
if (feof(infile)) {
break;
}
perror("fgetws()");
continue;
}
str[wcscspn(str, L"\r\n")] = L'\0';
if (fwprintf(outfile, L"%ls\n", str) < 0) {
perror("fwprintf()");
}
}
return 0;
}
それは、常にASCIIファイルと完璧に動作しますが、UTF-8のデータを読み込むときに、時にはそれがfgetws()
からEILSEQ
エラー(不正なバイト列)を取得し、私はその理由を把握することはできません。
出力ファイルで、エラーの原因となった行が切り捨てられ、いくつかの文字が欠落し、残りの部分が次の行にあります。 奇妙なことは、私がその行だけを与えると、私はエラーを起こさないということです。
たとえば、わずか数行のUTF-8回線でファイルを読み込んだ場合は問題ありません。同じ行を何回も繰り返すと、私はEILSEQ
になります。
私は、ファイルが正しくエンコードされていると確信しています。
私はmusl-libcでLinuxを使用しています。
私のコードで何が間違っていますか?
EDIT: は、私は、入力サイズに応じて、いくつかのEILSEQ
エラーが出ますが、私は2つのbeetween正確な関係を知りません。
同じ入力では、同じ行で同じエラーが発生します。
エラーを引き起こす特定のオフセットまたは文字ではないようですが、間違っている可能性があります。
EDIT 2: 私はこのコードをOpenBSDでもテストしています。この時点で、私はこの問題がLinuxやmusl-libcに関係していると考えています。
'STR = 0;'かもしれませんより良い方法。 – wildplasser
確かに。ありがとうございました。 –
ファイルの同じポイントで常に失敗しますか? EILSEQの1つまたは2つのエラーが発生しますか?エラーを引き起こす文字の正確なバイトオフセットとその文字のutf-8コードは何ですか? – rici