file_fgets_sscanf2.c |
---|
#include<stdio.h> #include<stdlib.h> #define BUF_SIZE 1024 int main(void){ FILE *fp; int num, area, gdp, pop2000, pop2050; char *ch_fgets; int ch_sscanf; char nation[256], region[256]; char buf[BUF_SIZE]; int line=1; fp=fopen("for_file5.5.1error0.txt", "r"); if(fp==NULL){ printf("Can't Open File\n"); exit(1); } while(1){ ch_fgets=fgets(buf, BUF_SIZE, fp); if(ch_fgets==NULL){ break; } ch_sscanf=sscanf(buf, "%d%s%s%d%d%d%d", &num, nation, region, &gdp, &area, &pop2000, &pop2050); if(ch_sscanf!=7){ printf("Read Error:buf=%spop2000=%d\tpop2050=%d\tch_sscanf=%d\n", buf, pop2000, pop2050, ch_sscanf); break; } printf("%d\t%s\t%s\t%d\t%d\t%d\t%d\n", num, nation, region, gdp, area, pop2000, pop2050); line++; } fclose(fp); return 0; } |
この例では、「ABCDE
」が「%d
」の書式に合わないので
読み込みエラーが発生します。
(pop2000
とpop2050
を表示してみると、
一つ前に読み込んだ値16928と22260のままです。自分で確認してください。)
そしてsscanf
関数の戻り値が7でなく5になっています。
では「ABCDE
」の代わりに次のような場合にどうなるかを確かめて、
sscanf
関数の戻り値で完全にエラー処理を行うことができないことを説明してください。
それぞれの場合のpop2000,pop2050,ch_sscanfの値を次の表に示します.
設定文字列 | pop2000 | pop2050 | ch_sscanf |
---|---|---|---|
123DE | 123 | 22260 | 6 |
AB34E | 16928 | 22260 | 5 |
ABC45 | 16928 | 22260 | 5 |
12.45 | 12 | 22260 | 6 |
pop2000が16928の場合やpop2050が22260の場合には35行目の項目が表示されているので 正しく読み込めていないことを示しています.
123DE,12.45は途中まで読み込んでいることで読み込みエラーになりません. これが最後列ならばエラーの有無を検知していないことになります. sscanf関数の戻り値を確認することは,エラーを検知できるものもあるので 無駄とは云えませんが,完全ではないことに注意しておく必要があります.
sscanf
関数の戻り値では完全にエラー処理を行うことができないことをより深く理解するために、
次のプログラムの動作を説明してください。
file_fgets_sscanf3.c |
---|
#include<stdio.h> #include<stdlib.h> #define BUF_SIZE 1024 int main(void){ FILE *fp; int data_i; double data_d; char data_s[BUF_SIZE]; char buf[BUF_SIZE]; char *ch_fgets; int ch_sscanf; fp=fopen("for_report7-2.txt", "r"); if(fp==NULL){ printf("Can't Open File\n"); exit(1); } while(1){ ch_fgets=fgets(buf, BUF_SIZE, fp); if(ch_fgets==NULL){ break; } ch_sscanf=sscanf(buf, "%d%lf%s", &data_i, &data_d, data_s); printf("ch_sscanf:%d\tdata_i:%d\tdata_d:%f\tdata_s:%s\n", ch_sscanf, data_i, data_d, data_s); } fclose(fp); return 0; } |
for_report7-2.txt |
---|
1 2.3 efghi 1 2 efghi 1 2.c efghi 1a 2.3 efghi 1.2 2.3 efghi |
for_report7-2result.txt |
---|
ch_sscanf:3 data_i:1 data_d:2.300000 data_s:efghi ch_sscanf:3 data_i:1 data_d:2.000000 data_s:efghi ch_sscanf:3 data_i:1 data_d:2.000000 data_s:c ch_sscanf:1 data_i:1 data_d:2.000000 data_s:c ch_sscanf:3 data_i:1 data_d:0.200000 data_s:2.3 |
sscanf
関数を用いて
整数、小数、文字列を読み込もうとして誤ったデータを読み込んだ場合の動作を
まとめて下さい。
sscanf関数は, 読み込む対象を先頭から読み込める部分だけ読み込み, 読み込めなかった部分は次の読み込みに回されます. 1文字も読み込めなかった場合にはそこで読み込みが中断されます.