テキスト ファイルが CSV 形式であること (つまり、各桁がコンマで区切られていること) を検証する必要があります。
オンラインで読むと、人々はそれについて相反する意見を持っているようですがStrtok()
、これを行う最善の方法は何ですか?
どんな助けでも素晴らしいでしょう。
あなたの入力はとても簡単なようですので、おそらくループアラウンドを使用するでしょうfgetc(3)
。ここでいくつかの擬似コードをスケッチします:
fd = fopen("file", "r");
int c;
while((c=fgetc(fd)) != EOF) {
switch(c) {
case '0':
case '1':
/* so on */
case '9':
handle_digit(c);
break;
case ',':
handle_comma();
break;
case '\n':
handle_newline();
break;
default:
fprintf(stderr, "mistaken input %c\n", c);
break;
}
}
fclose(fd);
数値のリストを取得するために実行するRubyやPythonなどの高級言語に慣れている場合は、関数の入力を少し厄介な方法で管理する必要がありますが、line.split(',')
かなり慣用的なCです。
もちろん、これが本当の問題である場合、私はおそらく、そして、小さなレクサーと文法を書くことを好みflex
ますbison
。これは主に、ニーズの変化に応じて将来拡張するのがはるかに簡単になるためです。
アップデート
チェックするいくつかの追加の基準を使用すると、handle_{digit,comma,newline}()
ルーチンをスケッチするのが簡単になります。グローバル変数を使用してスケッチしますが、これらをaに簡単に詰め込んでstruct
、関数間で渡すこともできます。
enum seen {
NEWLINE,
COMMA,
DIGIT,
};
enum seen last_seen = NEWLINE;
handle_digit(int c) {
if (last_seen == DIGIT) {
/* error if numbers cannot have multiple digits
or construct a larger number if numbers can have
multiple digits */
} else if (last_seen == COMMA || last_seen == NEWLINE) {
/* start a new entry */
}
last_seen = DIGIT;
}
handle_comma() {
if (last_seen == COMMA) {
/* error */
} else if (last_seen == NEWLINE) {
/* error */
} else if (last_seen == DIGIT) {
/* end previous field */
}
last_seen = COMMA;
}
handle_newline() {
if (last_seen == NEWLINE) {
/* error */
} else if (last_seen == COMMA) {
/* error */
} else if (last_seen == DIGIT) {
/* end previous field */
}
last_seen = NEWLINE;
}
使用しているルールに従ってコンテンツを検証するために必要なチェックを追加します。/* nop */
テストの順序と内容を標準化して、何かが問題ないことを思い出させるために1〜2回コメントを書くことを意味する場合でも、テストを決して忘れないようにすることをお勧めします。