| 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文字も読み込めなかった場合にはそこで読み込みが中断されます.