ページ 1 / 1
ファイルについて
Posted: 2007年3月21日(水) 09:14
by グー
このプログラムなんですけど、警告、エラーが出まくり。なんで?
ヘッダーとかも別に間違っていないと思うけど・・・・。
なんでだろ?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int sum;
int val;
double avg;
sum = 0;
avg = 0;
FILE *fp;
if(fp = fopen("test.txt","r") == NULL) {
printf("file open erroe\n");
return 1;
}
printf("file open\n");
for(i= 0; "" ; i++) {
fscanf(fp, "%d\n",&val);
if(val == 0) {
break;
}
sum = sum + val;
}
}
avg = sum / i;
printf("合計>>%d,平均>>%d",sum,avg);
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 09:26
by 組木紙織
気になる部分だけコメント入れてあります。
修正はしていないですが、修正すればコンパイルできると思います。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int sum;
int val;
double avg;
sum = 0;
avg = 0;
/*宣言位置が違う、先頭で定義していない。*/
FILE *fp;
/*優先順位の問題により先に[==]を考えている*/
if(fp = fopen("test.txt","r") == NULL) {
printf("file open erroe\n");
return 1;
}
printf("file open\n");
for(i= 0; "" ; i++) {
fscanf(fp, "%d\n",&val);
if(val == 0) {
break;
}
sum = sum + val;
}
/*括弧が一つ多い*/
}
avg = sum / i;
printf("合計>>%d,平均>>%d",sum,avg);
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 09:41
by グー
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp;
int i;
int sum;
int val;
double avg;
sum = 0;
avg = 0;
fp = fopen("test.txt","r");
if(fp == NULL) {
printf("file open erroe\n");
return 1;
}
printf("file open\n");
for(i= 0; ; i++) {
fscanf(fp, "%d\n",&val);
if(val == 0) {
break;
}
sum = sum + val;
}
avg = sum / i;
printf("合計>>%d,平均>>%d",sum,avg);
fclose(fp);
return 0;
}
こんな感じにしました。確かにコンパイルはできたのですが、avgに代入した値は使われていないとかで警告
が一つでました。そのまま実行したら、file openとだけでて動かなくなってしまいました。
Re:ファイルについて
Posted: 2007年3月21日(水) 09:49
by 組木紙織
まず[test.txt]の中身が気になります。最後が0で終わっていますか?
avgは最初に0で初期化してありますが、0で初期化する必要はこの場合ありませんよね?
コンパイラ0で初期化して、その値を使っていないということを警告しています。
最後にforの部分は無限ループとなるので[for(;;)]とするのが一般的だと思います。
その場合にはの宣言は必要なくなります。
これらの点に気をつけてみてください。
Re:ファイルについて
Posted: 2007年3月21日(水) 09:54
by グー
一応成功しました。test.txtの中身は
150
164
153
174
189
185
168
156
152
174
173
169
です。
for()の中の条件式をi < 12としたらできました。でも一々条件式かいていたら面倒ですね。
Re:ファイルについて
Posted: 2007年3月21日(水) 09:56
by 組木紙織
すみません
訂正です。
はループ以外の部分でも使っていました。
この場合は単純に無限ループだけに使っているわけではないので、問題ないです。
すみませんでした。
Re:ファイルについて
Posted: 2007年3月21日(水) 10:01
by グー
いえいえい。アドバイスありがとうございます。
ところで、for(;;)というのはどういうことなのでしょう?確かに私のテキストにもfor()文は条件式がありませんでした。
Re:ファイルについて
Posted: 2007年3月21日(水) 10:02
by 組木紙織
面倒でないようにするためには
1:テキストファイルの最後を0にする。
2:ファイルの終わりを確認する手段を入れる。
3:テキストファイルの先頭に要素の数を入れて、ループをその回数だけまわす。
といった手段があります。
Re:ファイルについて
Posted: 2007年3月21日(水) 10:11
by 組木紙織
簡単に説明すると、永久に続くループを作る手段の方法のひとつとでも覚えてください。
while(1){}も同じような効果があります。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i=0;
/*
永久にループが続くので
Ctrl + Cなどで止めてください
*/
for(;;){
printf("%d\n",i);
}
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 10:13
by グー
私の持っているテキストでは、こんなコードになっています。
while(fscanf(fp, "%d",&val) != EOF)の部分がよく分からないですね。
あと、cntが、未定義のシンボルとでてしまいます。なぜでしょう?
#include <stdio.h>
int main(void) {
FILE *fp;
int val;
int sum;
int cnt;
if((fp = fopen("test.txt","r")) == NULL) {
return 1;
}
printf("oprn\n");
cnt = 0;
while(fscanf(fp, "%d",&val) != EOF) {
sum = sum + val;
cont++;
}
if(cnt > 0) {
printf("合計>>%d,平均>>%d",sum,sum/cnt);
}
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 10:21
by 組木紙織
EOFはEnd OF Fileの略です。
ファイルの最後を示すものと考えてください。
>while(fscanf(fp, "%d",&val) != EOF) {
この部分でファイルが終わるまでループをまわし続けるという意味になります。
cntとcontありますが、タイプミスですか?
Re:ファイルについて
Posted: 2007年3月21日(水) 10:23
by グー
タイプミスです。
あと、scanfとsscanfがかいてあるのですが、どの様に違うのでしょう?sscanfを使うメリットとはなにか
あるのでしょか?
Re:ファイルについて
Posted: 2007年3月21日(水) 10:42
by 組木紙織
簡単に言うと
scanf()はコンソール入力から、sscanf()は文字列から入力元()を取るという違いがあります。
簡単に使い方を示しておきます。
#include <stdio.h>
int main(void) {
char string[/url] = "125 a";
int num;
char ch;
sscanf(string, "%d %c",&num, &ch);
printf("%d %c\n",num, ch);
return 0;
}
メリットは
scanf()はある一定の条件においてはプログラムが正しくない動きをすることがあり、
それを防ぐためにsscanf()を使うことが多いです。
というような感じです。
このことに関しては色々な場所で議論されているので調べてみたらどうでしょうか?
Re:ファイルについて
Posted: 2007年3月21日(水) 10:46
by グー
#include <stdio.h>
int main(void) {
FILE *fp;
int val;
int sum;
int cnt;
char buff[100];
if((fp = fopen("test.txt","r")) == NULL) {
return 1;
}
printf("oprn\n");
cnt = 0;
while(fgets(buff,buff[100],fp)) {
sscanf(buff,"%d",&val);
sum = sum + val;
cnt++;
}
if(cnt > 0) {
printf("合計>>%d,平均>>%d",sum,sum/cnt);
}
fclose(fp);
return 0;
}
これだと、コンパイルはできるのですが実行できないです。なぜか、ループ処理の中の条件式を
書かないと私のは動きませんね。やっぱりVisual stadioとか入れるべきなのかな?
後、fgets()ってファイルの読み込みとなっていますが、書き込みもできますよね?
fgets(第一引数、第二引数、stdin)として、fprintf()をつかってやれば?
Re:ファイルについて
Posted: 2007年3月21日(水) 11:29
by 組木紙織
私自身はVisual stadioは重いのであまり好きではないのですが、確かにあったほうが便利な部分は多いです。
本題に入りますが、
fget()の引数と、戻り値は何であるか知っていますか?
この場合はコンパイルが出来ても動作は正しく動かないです。
char *fgets(char *文字列, int 数値, FILE *ストリーム)
となっています。
今気をつけるのは二番目の引数の数値の部分と戻り値の部分です。
二番目の引数の意味は文字列に読み込む文字数を与えないといけないです。
上のプログラムでは文字列の100番目の部分にある部分を数値で読み取った場合の値となるので
通常は読み込む文字数をそのまま入れればよいでしょう。
戻り値ですが、この戻り値は文字列へのポインタを返しますので、whileの条件判断の部分に
入れるのは不適当だと思います。
fgets(buff,99,fp);
で入力して、
として終わりの判断はfeof()関数を使ってあげればよいかと思います。
fgets()だけでは書き込みは不可能です。
この関数は文字列の読み込みに使うだけなので、書き込むためには読み込んだ文字列を
別の関数を使って書き込みしないといけなくなります。
その意味ではfget(,,stdin)でコンソールから読み取った文字列をfprintf()でファイルに書き込むことはできますが。
Re:ファイルについて
Posted: 2007年3月21日(水) 12:21
by グー
組木紙織さん詳しい解説ありがとうございます。
なんか訳わからなくなってきてしまいました。私の持っているテキストって・・・一体・・。
Re:ファイルについて
Posted: 2007年3月21日(水) 12:39
by グー
ちょっと混乱したので基礎にもどります。
#include <stdio.h>
int main(void) {
FILE *fp;
int i;
int val;
int sum;
fp = fopen("test.txt","r");
if(fp == NULL) {
return 0;
}
printf("OPEN!!\n");
i = 0;
sum = 0;
while(fscanf(fp,"%d",&val) != EOF ){
sum = sum + val;
i++;
}
printf("合計:%d,平均:%d",sum,sum/i);
fclose(fp);
return 0;
}
これは成功したコードです。合計、平均がしっかりコンソールに出てきました。テキストファイルの中身は、
10
20
30
40
50
60
70
80
90です。
最初の方にwhile()の中身については教えていただいたので理解できました。
ただ、今度は文字列を読み込んでみようとおもうのですが、fscanf()ではダメですよね?
また、fscanf()だと色々と危険性の問題もあるようなので。
例えば、テキストファイルの中身がABCDEFという文字列だった場合です。文字列の場合はfgets()を使うの
でしょうか??
Re:ファイルについて
Posted: 2007年3月21日(水) 13:04
by グー
文字列の読み込みに成功しました。ファイルにはabcdefgと書いておき読み込んだものです。コードは↓
[/pre]
#include <stdio.h>
int main(void) {
FILE *fp;
int i;
char ch[20];
fp = fopen("test1.txt","r");
if(fp == NULL) {
return 1;
}
printf("OPEN!!\n");
for(i = 0; i < 8; i++){
fgets(&ch,20,fp);
}
/*
while(fgets(&ch,20,fp) != EOF){
i++;
}
*/
printf("%s",ch);
fclose(fp);
retrun 0;
}
[/pre]
for(i = 0; i < 8; i++)のところの条件式なのですが、今は読み込む数が少ないので数えれば分かるのですが、
数え切れないような量を読み込むときはどうしたらいいのでしょう?
また、最初はwhile()文(コメント部分)でやったのですが、コンパイルすらできませんでした。
0を検出するとか色々書いてあったのですが、よく分からなかったですね・・。ただwhile()の方が、
EOFとか使っているので、色々とトラブルは未然に防げるみたいですけど、なかなか理解できないです。
Re:ファイルについて
Posted: 2007年3月21日(水) 13:12
by 組木紙織
文字列を入れる配列の大きさを十分大きくすればfscanf()でも問題はないです。
ABCDEFの文字列だと要素が7以上あれば問題はないです。(何で7以上か分かりますか?)
また引数の部分を"%s"ではなく"%6s"として取り込む文字数を指定することが出来ます。
fget()の場合は、取り込む文字数を指定しているので配列のサイズを取り込む文字数以上にしておけば
問題はないです。
文字列の場合fscanf()もfget()も取り込む文字数と配列のサイズとの兼ね合いを気をつけておけば
問題はないと思います。
Re:ファイルについて
Posted: 2007年3月21日(水) 13:24
by グー
>>ABCDEFの文字列だと要素が7以上あれば問題はないです。(何で7以上か分かりますか?)
char型は1バイトでabcdefで6バイト、それで最後の\0も必要だからですか?
後、私が書いたコードのfor()の条件式なのですが、i<1としてもしっかりと読み取れます。これはどういうことでしょう?
Re:ファイルについて
Posted: 2007年3月21日(水) 13:41
by 組木紙織
>char型は1バイトでabcdefで6バイト、それで最後の\0も必要だからですか?
そうです。文字列を扱うときには最後の\0を意識して扱う必要があります。
>後、私が書いたコードのfor()の条件式なのですが、i<1としてもしっかりと読み取れます。これはどういうこ>とでしょう?
テキストファイルの中身を
abcdefghijklmnopqrtsuvwxyz
このようにして次のプログラムを実行してみてください。
で考えてみてください。
ポイントはfget()が何処まで文字を読み取るか?と、fget()は何をバッファに入れるか?ということです。
#include <stdio.h>
int main(void) {
FILE *fp;
int i;
char ch[20];
fp = fopen("test1.txt","r");
if(fp == NULL) {
return 1;
}
printf("OPEN!!\n");
fgets(&ch[0],20,fp);
printf("%s\n",ch);
fgets(&ch[1],20,fp);
printf("%s\n",ch);
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 13:46
by box
> for(i = 0; i < 8; i++){
> fgets(&ch,20,fp);
> }
ここのループの、変数 i の意味と、fgets 関数の第1引数の意味を教えてくださいますか?
ファイルポインタ fp から、最大20バイトを、どこへ格納しようとしているのでしょうか?
ch のアドレスでよいのでしょうか?
Re:ファイルについて
Posted: 2007年3月21日(水) 14:01
by グー
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]
a b c d e f g h i j k l m n o p q r s t u
↑
fgets(&ch[0],20,fp);の第二引数が20だからchar[0]から20個読み取りなさいということでここまで読み込んだ。それで最後に\0が来るから実際に文字を読み込んでいるのは19個。\0もあわせて20個20バイトになる。
fgets(&ch[1],20,fp);はatuvwzとでてきました。よく分からないです。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:08
by 組木紙織
一番のポイントはfget()は文字列を扱うということです。
一度目のfget()で読み込み文字列
abcdefghijklmnopqrs
&ch[0]に代入
↓ここから代入
ch[0] ch[1] ch[2] ch[3] ch[4] ch[5] . . .
+++++++++++++++++++++++++++++++++++++++++++++++++
+ + + + + + +
+ a + b + c + d + e + f +
+ + + + + + +
+++++++++++++++++++++++++++++++++++++++++++++++++
二度目のfget()で読み込む文字列
tuvwxyz
&ch[1]に代入
↓ここから代入
ch[0] ch[1] ch[2] ch[3] ch[4] ch[5] . . .
+++++++++++++++++++++++++++++++++++++++++++++++++
+ + + + + + +
+ a + t + u + v + w + x +
+ + + + + + +
+++++++++++++++++++++++++++++++++++++++++++++++++
Re:ファイルについて
Posted: 2007年3月21日(水) 14:12
by グー
なるほど~。
でも、二回目の読み込みのとき aも出てきてしまったのは?
Re:ファイルについて
Posted: 2007年3月21日(水) 14:19
by 組木紙織
>printf("%s\n",ch);
は文字列を何処から表示するのでしょうか?
ch[0]? ch[1]?
Re:ファイルについて
Posted: 2007年3月21日(水) 14:25
by グー
う~・・・aからですか?
でも、aは二回も表示させてくないですよね。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:35
by 組木紙織
そうですね。
通常は上記のような扱い方をしません。
通常は
fget(ch,20,fp);
といったような使い方をします。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:43
by グー
>>通常fget(ch,20,fp); といったような使い方をします
そしたらfor()は意味がないですよね??
Re:ファイルについて
Posted: 2007年3月21日(水) 14:46
by グー
やっぱりなぜaから二回目も出てくるのか分からないです。
>printf("%s\n",ch);
は文字列を何処から表示するのでしょうか?
ch[0]? ch[1]?
がわからないですね?なぜaからなのか。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:47
by 組木紙織
はい。そのとおりです。
for()なしで問題のプログラムを実行してみましたか?
問題なく動くと思います。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:53
by 組木紙織
printf("%s",ch);
を
int i=0;
for(;;){
if(ch == '\0')break;
printf("%c",ch);
i++;
}
と考えたら分かると思います。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:55
by グー
for文使わないでもできました。
Re:ファイルについて
Posted: 2007年3月21日(水) 14:58
by グー
上のコード実行しても何もおきないのですが・・・・。
Re:ファイルについて
Posted: 2007年3月21日(水) 15:03
by グー
コードの実行できました。a~sまでが二回でてきました。
でも良く分からない。。
Re:ファイルについて
Posted: 2007年3月21日(水) 15:06
by グー
実行したコードはこれです。
#include <stdio.h>
int main(void) {
FILE *fp;
int i;
char ch[20];
fp = fopen("test1.txt","r");
if(fp == NULL) {
return 1;
}
printf("OPEN!!\n");
fgets(ch,20,fp);
i=0;
for(;;){
if(ch == '\0')break;
printf("%c",ch);
i++;
}
printf("%s\n",ch) ;
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 15:08
by 組木紙織
上のコードは考え方だけなのでそのままでは実行出来ないはずです。
一通り形にしてみると次のようになります。
#include <stdio.h>
int main(void) {
char ch[/url] = "abcde";
int i;
/* %sを使った場合*/
printf("%s",ch);
printf("\n");
/*%sを%cとループで代用した場合*/
i=0;
for(;;){
/*ここを注意深くみてください*/
if(ch == '\0')break;
printf("%c",ch);
i++;
}
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 15:30
by グー
なんとか自分なりに理解できました。
後、気になっていたのですが、数字を読み取る時にEOFを使ったじゃないですか。あれって文字列の時は使わなくていいのですか?
Re:ファイルについて
Posted: 2007年3月21日(水) 15:33
by むつ
ファイルから複数行読み取る際には、ファイルの終端(EOF)がわからないといけないですよね。
次のステップは、複数行の読み取りでしょうかね。
※ch[ここに一行分格納できるだけのサイズ]
※fgets( ch, ここのサイズを決定する, fp );
その後、ここをご覧ください。
http://www.bohyoh.com/CandCPP/C/Library/fgets.html
【 改行文字 】を読み取ったとき、
またはファイルの終わりを検出したときに、文字の読取りは終了し、
【 読み取った改行文字 】も配列に格納する。
このように、chへ取り込まれた改行をなくしたいなら、
'\0'で置き換える作業が必要かと思います。
Re:ファイルについて
Posted: 2007年3月21日(水) 16:17
by グー
むつさんありがとうございます。
今、数値をfgets()で読み取り、数値に変換して計算するということをやっています。
#include <stdio.h>
int main(){
FILE *fp;
char ch[20];
int i;
int sum = 0;
int val;
fp = fopen("test.txt","r");
if(fp == NULL) {
return 1;
}
printf("ok\n");
i = 0;
sum = 0;
while(fgets(ch,20,fp)){
sscanf(ch,"%d",&val);
sum = sum + val;
i++;
}
printf("%d",sum);
fclose(fp);
return 0;
}
while(fgets(ch,20,fp))のところが良く分からないですね・・・。
whileってループですよね?条件式とかもないし。どういうことなんでしょう?fgets()の中身は
だいぶ分かってきました。
Re:ファイルについて
Posted: 2007年3月21日(水) 16:37
by グー
ファイルに出力する問題でテキストの練習問題解いているのですが、実行するとエラーになってしまいます。どこがおかしいのでしょうか?scanfで入力させるのは良くないですかね?
#include <stdio.h>
int main(void) {
FILE *fp;
char no[10];
char name[20];
char point[10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
printf("エラーです\n");
return 1;
}
printf("FILE OPEN\n");
for(i = 0; i < 3; i++) {
printf("%d人目の入力\n");
scanf("%s",no);
scanf("%s",name);
scanf("%s",point);
}
for(i =0; i < 3; i++) {
fprintf(fp,"%s\n",no);
fprintf(fp,"%s\n",name);
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 16:49
by バグ
scanfの引数はアドレスじゃなかったかと…?
滅多に使わないから、うろ覚えなので、間違ってたらすみません…m(__)m
Re:ファイルについて
Posted: 2007年3月21日(水) 16:52
by グー
今アドレス&を付けて実行したら、入力はできるのですが、入力が終わるとエラーになってしまいます。
Re:ファイルについて
Posted: 2007年3月21日(水) 16:55
by miyaza
printf("%d人目の入力\n");の%dにあてはまる変数や値がないからです。
scanf("%s",no);
としていますがこれでは、一人目の人のデータを入力した後、二人目の人のデータを入力したときno[1]の部分から上書きしてしまうことになります。
name
point
も同様です。
3人分のデータを保存するのなら二次元配列にすることをおすすめします。
Re:ファイルについて
Posted: 2007年3月21日(水) 16:59
by miyaza
> printf("%d人目の入力\n");の%dにあてはまる変数や値がないからです。
関係ありませんでした。しかし値は必要だと思います。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:01
by グー
miyazaさんありがとうございます。できました。こういうことですね。
#include <stdio.h>
int main(void) {
FILE *fp;
char no[3][10];
char name[3][20];
char point[3][10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
printf("エラーです\n");
return 1;
}
printf("FILE OPEN\n");
for(i = 0; i < 3; i++) {
printf("%d人目の入力\n",i + 1);
scanf("%s",&no);
scanf("%s",&name);
scanf("%s",&point);
}
for(i =0; i < 3; i++) {
fprintf(fp,"%s\n",no);
fprintf(fp,"%s\n",name);
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
コンソールから入力させるときはscanf()よりもいい方法ないですかね?scanf()はあまりよくないみたいで。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:03
by むつ
入力した内容を、直接ファイルに格納し、
なおかつ、no[/url]、name[/url]、point[/url]を以後使わないのであれば、
以下のようになると思います。
#include <stdio.h>
int main(void) {
FILE *fp;
char no[10];
char name[20];
char point[10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
printf("エラーです\n");
return 1;
}
printf("FILE OPEN\n");
for(i = 1; i <= 3; i++) {
printf("%d人目の入力\n", i );
scanf("%s", &no);
scanf("%s", &name);
scanf("%s", &point);
//
fprintf(fp,"%s\n",no );
fprintf(fp,"%s\n",name );
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 17:05
by miyaza
> コンソールから入力させるときはscanf()よりもいい方法ないですかね?scanf()はあまりよくないみたいで。
fgets()を使ってみたらどうでしょう。
fgets(no,sizeof(no),stdin);
こんな感じで
Re:ファイルについて
Posted: 2007年3月21日(水) 17:08
by グー
fgets()って読み込むときじゃないんですか??
scanf()よりもメリットあるのでしょうか??というより、fgets()でもコンソールから入力させられるなんて!!
Re:ファイルについて
Posted: 2007年3月21日(水) 17:14
by miyaza
> fgets()って読み込むときじゃないんですか??
読み込んでますよ。標準入力から、だからfgets()の第三引数をstdinとしています。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:18
by グー
なるほど!確かに読み込んでいますよね。標準入力から。説得力ありますよ。
fgets()で読み込むメリットってなんすかね?質問ばかりですみません。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:30
by miyaza
> fgets()で読み込むメリットってなんすかね?質問ばかりですみません。
一行だけ読み取れます。スペースも読み取れる。メリットというかscanf()との違いですが。
逆に聞きますがなんでscanf()よくないんでしょうか?
Re:ファイルについて
Posted: 2007年3月21日(水) 17:32
by グー
一度目はしっかりと読み込めたのですが、2回目3回目読み込むと、数字がめちゃくちゃになっているのですが、どういうことでしょうか?
#include <stdio.h>
int main(void) {
FILE *fp;
char no[3][10];
char name[3][20];
char point[3][10];
int i;
int val;
int sum;
fp = fopen("student.txt","r");
if(fp == NULL) {
printf("エラーです\n");
return 1;
}
printf("FILE OPEN\n");
/*
//書き込み用
for(i = 0; i < 3; i++) {
printf("%d人目の入力\n",i + 1);
scanf("%s",&no);
scanf("%s",&name);
scanf("%s",&point);
}
for(i =0; i < 3; i++) {
fprintf(fp,"%s\n",no);
fprintf(fp,"%s\n",name);
fprintf(fp,"%s\n",point);
}
*/
//読み込み用
sum = 0;
for(i = 0; i < 3; i++) {
fgets(no,10,fp);
fgets(name,20,fp);
fgets(point,10,fp);
//sscanf(point,"%d",&val);
//sum = sum + val;
}
for(i = 0; i < 3; i++) {
printf("%s\n",no[i]);
printf("%s\n",name[i]);
printf("%d\n",&point[i]);
}
printf("合計%d",sum);
fclose(fp);
return 0;
}
Re:ファイルについて
Posted: 2007年3月21日(水) 17:48
by むつ
今、入力した内容を直接ファイルに書き込んでいるので
書き込みの方で、for文を2つに分ける必要がありません。
以下に示したように、1つのfor文で処理してはいかがでしょう。
また、書き込みの方で、入力内容は一時的に格納するだけですので、
no[/url]、name[/url]、point[/url]に格納する必要は無いですよ。
もう1つchar buf[ 256 ];というのを用意して、
以下のようにしてみてください。
for( i = 1; i < 3; i++ ) {
printf( "%d人目の入力\n",i );
scanf( "%s", &buf );
fprintf( fp, "%s\n", buf );
scanf( "%s", &buf );
fprintf( fp, "%s\n", buf );
scanf( "%s", &buf );
fprintf( fp, "%s\n", buf );
}
そして、読み込み側ですが、fclose()によって、ファイルの書き込みが実行されます。
fclose()する前に、fpからfget()しても、入力した内容は取得できないのではないでしょうか。
ファイルが変更された後の、最新情報を取得したいのであれば、
書き込み側のfpをfclose()した後に続いて、読み込み用にfopen()してください。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:52
by miyaza
> 一度目はしっかりと読み込めたのですが、2回目3回目読み込むと、数字がめちゃくちゃになっているのですが、どういうことでしょうか?
printf("%d\n",&point);
これではアドレスを渡していることになります。
printf("%s\n",point);
とすればだいじょうぶです。
Re:ファイルについて
Posted: 2007年3月21日(水) 17:57
by グー
miyazaさんへ
>逆に聞きますがなんでscanf()よくないんでしょうか?
私はまだまだ初心者なので分かりませんが、あまり使わないほうがいいみたいです。理由はよくわからないの です。。
むつさんへ
たしかにそのやり方のほうがいいかもしれませんね!手間が省けますからね。
Re:ファイルについて
Posted: 2007年3月21日(水) 18:15
by グー
miyazaさんありがとうございます。できました。
Re:ファイルについて
Posted: 2007年3月21日(水) 18:20
by グー
pointを文字列として読み込んだあとに数値に変換して合計を求めたいのですが、何か方法ありますかね?
なかなかうまくいかなくて困ってます。
Re:ファイルについて
Posted: 2007年3月21日(水) 18:25
by miyaza
先ほどグーさんが書かれたソースの下の部分コメントアウトをはずしたら問題なくできましたが。
//sscanf(point,"%d",&val);
//sum = sum + val;
Re:ファイルについて
Posted: 2007年3月21日(水) 18:35
by グー
そうですか。できましたか。なぜかわたしのはできない。もう一度試してみます!
Re:ファイルについて
Posted: 2007年3月21日(水) 18:37
by グー
合計がやっぱり違う・・・・
Re:ファイルについて
Posted: 2007年3月21日(水) 18:54
by box
> 合計がやっぱり違う・・・・
案に相違してうまくいかない場合は、
とにかくそのソースを提示するのが得策でありましょう。
「このソースを書いてみたのですが、合計がやっぱり違います」
という風にすれば、本来は不要な発言のキャッチボールをしなくてすみます。
Re:ファイルについて
Posted: 2007年3月21日(水) 19:26
by バグ
合計が違うのであれば、『計算部分』か『データの代入部分』のどちらかに間違いがあるのでしょう。
Re:ファイルについて
Posted: 2007年3月21日(水) 19:53
by グー
#include <stdio.h>
int main(void) {
FILE *fp;
char no[3][10];
char name[3][20];
char point[3][10];
char buf[256];
int i;
int val;
int sum;
fp = fopen("student.txt","r");
if(fp == NULL) {
printf("エラーです\n");
return 1;
}
printf("FILE OPEN\n");
sum = 0;
for(i = 0; i < 3; i++) {
fgets(no,10,fp);
fgets(name,20,fp);
fgets(point,10,fp);
scanf(point,"%d",&val);
sum = sum + val;
}
for(i = 0; i < 3; i++) {
printf("%s\n",no);
printf("%s\n",name);
printf("%s\n",point);
}
printf("合計%d",sum);
fclose(fp);
return 0;
}
テキストファイルを文字列で読み込み、pointだけ数値に変換してpointの合計を出力しようとしたものです。
Re:ファイルについて
Posted: 2007年3月21日(水) 20:00
by miyaza
scanf(point,"%d",&val);
ではなく
sscanf(point,"%d",&val);
としてください
sが一個たりませんでしたね。
Re:ファイルについて
Posted: 2007年3月21日(水) 20:09
by 管理人
Re:ファイルについて
Posted: 2007年3月21日(水) 20:15
by グー
miyazaさん了解です!
管理人さんありがとうございます!<!--12-->
Re:ファイルについて
Posted: 2007年3月22日(木) 09:34
by グー
//読み込みコード
#include <stdio.h>
#define NUM 2
int main(void) {
FILE *fp;
char no[NUM][10];
char name[NUM][20];
char point[NUM][10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
return 1;
}
printf("FILE OPEN\n");
for(i = 0; i < NUM; i++) {
printf("%d人目",i + 1) ;
printf("NO>>>");
scanf("%s",&no);
fprintf(fp,"NO:%s\n",no);
printf("NAME>>>");
scanf("%s",&name);
fprintf(fp,"%s\n",name);
printf("POINT>>>");
scanf("%s",point);
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
//書き込みコード
#include <stdio.h>
#define NUM 2
int main(void) {
FILE *fp;
char no[NUM][10];
char name[NUM][20];
char point[NUM][10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
return 1;
}
printf("FILE OPEN\n");
for(i = 0; i < NUM; i++) {
printf("%d人目",i + 1) ;
printf("NO>>>");
scanf("%s",&no);
fprintf(fp,"NO:%s\n",no);
printf("NAME>>>");
scanf("%s",&name);
fprintf(fp,"%s\n",name);
printf("POINT>>>");
scanf("%s",point);
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
もっとこうしたほうがのでは?と思うところご指摘下さい
Re:ファイルについて
Posted: 2007年3月22日(木) 09:52
by グー
#include <stdio.h>
#define NUM 2
int main(void) {
FILE *fp;
char no[NUM][10];
char name[NUM][20];
char point[NUM][10];
int i;
fp = fopen("student.txt","w");
if(fp == NULL) {
return 1;
}
printf("FILE OPEN\n");
for(i = 0; i < NUM; i++) {
printf("%d人目",i + 1) ;
printf("NO>>>");
scanf("%s",&no);
fprintf(fp,"NO:%s\n",no);
printf("NAME>>>");
scanf("%s",&name);
fprintf(fp,"%s\n",name);
printf("POINT>>>");
scanf("%s",point);
fprintf(fp,"%s\n",point);
}
fclose(fp);
return 0;
}
#include <stdio.h>
#define NUM 2
int main(void) {
FILE *fp;
char no[NUM][10];
char name[NUM][20];
char point[NUM][10];
int i;
int val;
int sum;
fp = fopen("student.txt","r");
if(fp == NULL) {
return 1;
}
printf("FILE OPEN\n");
sum = 0;
for(i = 0; i < NUM; i++) {
printf("%d人目\n",i + 1);
fgets(no,10,fp);
printf("%s\n",no);
fgets(name,20,fp);
printf("%s\n",name);
fgets(point,10,fp);
printf("%s\n",point);
sscanf(point,"%d",&val);
sum = sum + val;
}
printf("合計>>%d",sum);
fclose(fp);
return 0;
}
sscanf(point,"%d",&val);のvalの前に&がある理由って?
fgets(point,10,fp);
printf("%s\n",point);
sscanf(point,"%d",&val);
一度、pointに読み込んだものが格納されて、printfのpointで出力されているのは分かるのですが、sscanf
では、どのような処理がされているのでしょうか?&valで読み込んだものが、pointに格納され、sum = sum + valがされるのでしょうか?
Re:ファイルについて
Posted: 2007年3月22日(木) 10:42
by miyaza
> sscanf(point,"%d",&val);のvalの前に&がある理由って?
valのアドレスを渡しているからです。
sscanf()は指定された文字列から指定された書式フォーマットにしたがって変換されたデータを指定されたアドレスに格納します。
sscanf(point,"%d",&val);
今回pointの中にはfgets(point,10,fp);で取り込んだ文字列が入っています。その中から整数を変数valに格納しています。
つまり文字列の中から数値を取り出しています。
Re:ファイルについて
Posted: 2007年3月23日(金) 05:58
by グー
miyazaさんへ
ありがとうございます。