|
fgetc()で書いてみた。
ただし、マルチバイト文字を含むデータを想定していない。
int型のcをchar型のsにというのはどうも抵抗があるのですが。
今回のケースでは問題ありません。
極々簡単に言うと、エラー判定にchar型では表現できないからです。
(char)-1 == 0xff で、(unsigned char)0xff == 255 となるが、
バイナリデータの場合など、0xffは有効なデータとなりうるので、
そのままでは使えない。そこで、拡張し、int型にした。
そういった訳なので、今回の場合はキャストしてしまって問題ありません。
#include <stdio.h> // FILE, BUFSIZ, EOF, fgetc, feof, printf, fprintf
#include <stdlib.h> // exit
#include <string.h> // memset
#include <ctype.h> // isspace, isalpha, isdigit
// 任意の文字タイプのデータをバッファにコピーし、コピーしたバイト数を返す
int getValue(char *pBuff, int bufsiz, FILE *fp, int (*pfn)(int))
{
int c, i;
// バッファをゼロクリア
memset(pBuff, 0, bufsiz);
// 空白文字類をスキップ
for(c = fgetc(fp); c != EOF && isspace(c); c = fgetc(fp));
// 該当文字をコピー
for(i = 0; i < bufsiz && c != EOF; i++){
if(!pfn(c)){
break;
}
*pBuff = (char)c;
pBuff++;
c = fgetc(fp);
}
return i;
}
int main(void)
{
FILE *fpin = NULL;
char ken[BUFSIZ], ini[BUFSIZ], tel[BUFSIZ];
fpin = fopen("TEST.txt", "r");
if(fpin == NULL){
printf("can't open\n");
exit(1);
}
for(;;){
if( 0 == getValue(ken, BUFSIZ, fpin, isalpha) ||
0 == getValue(ini, BUFSIZ, fpin, isalpha) ||
0 == getValue(tel, BUFSIZ, fpin, isdigit) )
{
if(!feof(fpin)){
// ファイルの終端以外でデータの解析に失敗
fprintf(stderr, "データが不正です。\n");
}
break;
}
printf("%s\t%s\t%s\n", tel, ini, ken);
}
fclose(fpin);
return 0;
}
|