ページ 11

ファイル入出力

Posted: 2007年3月26日(月) 19:32
by のん
独学で勉強しているのですが、ファイルの入出力がさっぱり分かりません。テキストは独習Cを使っています。
イマイチ本の説明が分からないです。

getchar()>>一文字読み込む(キーボードから次に入力された文字を返す。データーの読み取りでエラーが出た場合はEOFを返す)

①この返すという意味は一体なんでしょう?返されたものはコンソールとかに出てくるのでしょうか?

②getche(),putch()という非標準のものも説明されていますが、実際使うことあるのですか?標準を使うべきか非標準を使うべきか混乱しています。

③次のコードを見てください
int main(void) {
  char *p,str[80];
  printf("文字列を入力してください\n");
  p = gets(str);
  if(p){
     printf("%s,%s",p,str);
  }
   return 0;
}

if(*p)じゃなくてなんでif(p)なのでしょうか?pにstrのアドレスを入れているのはわかるのですが。
あと、このコードって別にポインタを使わなくてもいいですよね?str自体が文字列のポインタだえすからね?

Re:ファイル入出力

Posted: 2007年3月26日(月) 19:41
by のん
質問の追加です。
④fgets(),fputs()とfgetc(),fputs()の違いってなんですか?
また、どちらを通常つかうべきでしょうか?

Re:ファイル入出力

Posted: 2007年3月26日(月) 19:46
by miyaza
> ①この返すという意味は一体なんでしょう?返されたものはコンソールとかに出てくるのでしょうか?
関数の戻り値です。コンソールには表示されません。

ch = getchar() などとした場合に正常ならば読み取った文字をchに格納してエラーしたらEOFを格納します。

Re:ファイル入出力

Posted: 2007年3月26日(月) 19:57
by のん
解説ありがとうございます。

Re:ファイル入出力

Posted: 2007年3月26日(月) 20:26
by のん
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[/url]) {
	FILE *fp;
	char str[80];

	if(argc != 2) {
		return 1;
		printf("ファイル名の入力\n");
	}
	
	fp = fopen(argv[1],"w");
	if(fp == NULL) {
		printf("エラー\n");
		return 1;
	}

	printf("終了するには空白行くを入力\n");
	
	do{
		printf(": ");
		gets(str);
	    strcat(str, "\n");
		if(*str != '\n') {
			fputs(str,fp);
		}
	}while(*str != '\n');

	fclose(fp);
	return 0;
}
①実行しファイル名を入力するとバッチファイルとして認識していませんと出ます。なぜでしょう?
②コマンドライン引数がイマイチ分からないです。何が何を指しているのか?
③このコードはファイル名を入力させますが、実行するとファイルは自動的に作られるのでしょうか?
fp = fopen("test.txt","w");としたときはファイルがないときは作られると思うのですが。
④printf("終了するには空白行くを入力\n");とありますが、空白というのは、ENTERを押したらということ
なのでしょうか?それともスペース?
⑤do whileのなかのif文の動作がよく理解できないです。改行がないときは書き込みするというのは分かるのですが、
gets()ってのは一行読み取るをけですよね?つまり改行まで?・・・・

質問ばかりしてすみません。

Re:ファイル入出力

Posted: 2007年3月26日(月) 20:56
by miyaza
> ①実行しファイル名を入力するとバッチファイルとして認識していませんと出ます。なぜでしょう?
実行時のファイル名してはどのようにしているのでしょうか?

実行ファイル名 作成ファイル名

とコマンドラインから入力しているでしょうか。たとえば実行ファル名をa.exeとして作りたいファイルをtest.txtとした場合

a.exe test.txt

となります。このときa.exeの後ろのtest.txtの部分がコマンドライン引数です。

>③このコードはファイル名を入力させますが、実行するとファイルは自動的に作られるのでしょうか?
作られます。

>④printf("終了するには空白行くを入力\n");とありますが、空白というのは、ENTERを押したらということ
なのでしょうか?それともスペース?
改行ですからENTERを押したらということになります。

Re:ファイル入出力

Posted: 2007年3月26日(月) 21:03
by miyaza
>⑤do whileのなかのif文の動作がよく理解できないです。改行がないときは書き込みするというのは分かるのですが、

strの一文字目が'\n'かどうかを調べてそうでなければ文字列strをfpに書き出します。

Re:ファイル入出力

Posted: 2007年3月26日(月) 21:26
by のん
miyazaさん分かりやすい解説ありがとうございます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 08:25
by のん
if(*str != '\n')のところせすが、if(str !='\n')にしてないのはなぜでしょう?

Re:ファイル入出力

Posted: 2007年3月27日(火) 08:40
by miyaza
> if(*str != '\n')のところせすが、if(str !='\n')にしてないのはなぜでしょう?
先頭の文字を調べているからです。*を付けると先頭の内容を参照できます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 08:49
by のん
miyazaさんありがとうございます。

2007/03/26(月) 20:26 のコードなんですが、正常に動かないのですが・・・

Re:ファイル入出力

Posted: 2007年3月27日(火) 08:58
by のん
fp = fopen(argv[1],"w");のところでC:\vc\P_test1\ex01.c(14) : warning C4047: 'function' : 間接参照のレベルが 'const char *' と 'char ' で異なっています。と出てしまいます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:04
by 組木紙織
何処がどんな風に正常に動かないかを教えてください。
そしてどのように動くのが正常であるかを教えてください。
それが分からないとどうすることが出来ません。

一般的な注意事項をなので気をつけてください。
多分ですがこの場合は
if(argc != 2) {
		return 1;
		printf("ファイル名の入力\n");
	}
この部分を
if(argc != 2) {
		printf("ファイル名の入力\n");
		return 1;
	}
少なくともコードを書いた意味を考えると、
このように修正します。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:13
by のん
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char argv[/url]) {
	FILE *fp;
	char str[80];

	if(argc != 2) {
		printf("error\n");
		return 1;
	}
	printf("ファイル名入力\n");
	fp = fopen(argv[1],"w");
	if(fp == NULL) {
		return 1;
	}


	printf("終了は空白行入力\n");
	do {
		printf(": ");
		gets(str);
		if(*str != '\n') {
			fputs(str,fp);
		}
	}while(*str != '\n');
	fclose(fp);
	return 0;
}
ちょっと書き換えてみました。でもファイル名の入力とかまでいかないでイッキにプログラムの最後まで行って
しまいます。出力されるのは、errorだけです。なぜでしょうか?

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:30
by 組木紙織
独習Cのp200のあたりを見直してください。
main関数の引数を注意深くみてください。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:36
by のん
組木紙織 さんも独習もってるのですか?全部理解できます?ループなんかすごく分かりにくい書き方してる
感じなんですけど。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:40
by のん
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char argv[/url]) {
	FILE *fp;
	char str[80];

	if(argc !=2) {
		printf("ふぁいる名を指定\n");
		return 1;
	}

	if((fp =fopen(argv[1],"w")) == NULL) {
		printf("ファイルを開けません\n");
		return 1;
	}

	printf("終了するには空白行入力\n");
	do{
		printf(": ");
		gets(str);
		if(*str !='\n'){
			fputs(str,fp);
		}
	}while(*str !='\n');

	fclose(fp);

	return 0;
}
テキストのコードそのままかきました。警告がでるのですが。

vc\P_test1\ex01.c(14) : warning C4047: 'function' : 間接参照のレベルが 'const char *' と 'char ' で異なっています。
C:\vc\P_test1\ex01.c(14) : warning C4024: 'fopen' : の型が 1 の仮引数および実引数と異なります。
C:\vc\P_test1\ex01.c(22) : warning C4020: 'gets' : 実引数が多すぎます。
リンク中...

ex01.exe - エラー 0、警告 3

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:44
by 組木紙織
ファイル入出力の部分のループですか?
一通り全部読んで理解はしましたが、分かりにくい部分もありますね。

コードを書いて、コンパイルして、改変をして、見直して、
というのを繰り返せばそのうち理解できるとおもいます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:46
by 組木紙織
int main(int argc, char * argv[/url])

を忘れています。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:49
by のん
if(argc !=2) {
printf("ふぁいる名を指定\n");
return 1;
}

とコマンドライン引数がよくわからないですね。フルグラムの名前ってなんですか?ソースファイル名のこと?

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:53
by のん
組木紙織さんありがとうございます。警告でなくなりましたが、実行すると、やはり
    if(argc !=2) {
		printf("ふぁいる名を指定\n");
		return 1;
のところのreturn 1;に行ってプログラムが終わってしまいます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:56
by なぎ
最初の2つの警告は、
int main(int argc, char argv[/url])
の行が間違っているためです。確認してみてください。
最後の警告は、このソースでは出ないはずですが?

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:58
by miyaza
コマンドライン引数を指定していますか?
コマンドライン引数はmain()関数に渡せる引数です。
実行するときどのようにしているのでしょうか?

Re:ファイル入出力

Posted: 2007年3月27日(火) 09:59
by なぎ
警告については、既に回答がついた後でしたね。

> のところのreturn 1;に行ってプログラムが終わってしまいます。

それは、実行時に、ファイル名を指定していないからでは?
プログラムの名前の後ろに、(スペース明けて)ファイル名を指定してください。

ex01 test.txt

こんな感じ。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:07
by miyaza
if(argc !=2) {
printf("ふぁいる名を指定\n");
return 1;
}
ここの部分argcの中には、コマンドライン引数の総数が入ります。総数には実行ファイル名も含まれます。

たとえば

a.exe test.txt

としたときargcには2が入ります。上のコードの判定部分では、引数の数を調べることによってファイル名が入力されたかを調べています。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:12
by のん
コンソールから実行ファイル名とか入力するのですよね?
私の場合なぜか、何も文字が打てないのですけど。
Visual Stdio 6.0をつかってるのですが・・・・。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:14
by miyaza
実行時にコマンドプロントまたはDOSプロントから実行して下さい。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:16
by バグ
コマンドプロンプトからファイル名を指定して実行していますか?
VC++6.0から直接実行していては、コマンドライン引数を指定する事は出来ないと思います。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:18
by のん
コマンドプロンプトから実行ってことはファイルがあるところまで移動してからでうしょね?

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:20
by miyaza
>コマンドプロンプトから実行ってことはファイルがあるところまで移動してからでうしょね?
そうです。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:23
by のん
ソースファイル名ex01.cの場合プロンプトから、ex01.exe test.txtとしましたが、ダメでした。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:26
by miyaza
> ソースファイル名ex01.cの場合プロンプトから、ex01.exe test.txtとしましたが、ダメでした。
具体的にどうなりましたか?

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:30
by のん
バッチファイルとして認識していないとでました。

ディレクトリは、vcというものの中にP_test1というフォルダを作りそのなかにex01.cというソースファイル
があります。

プロンプトからvcまでは移動できるのですが、P_test1までは移動できないですね??

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:33
by miyaza
ex01.exeはその中に存在していますか?
ex01.exeがないと実行できませんよ。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:35
by のん
P_test1フォルダまで移動できました!!が、ex01.exe test.txtとすると内部コマンドまたは外部コナンドとして操作可能なプログラム、バッチファイルとして認識していないとでます。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:39
by miyaza
'ex01.exe'は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
とでたらex01.exeが無いようなものだとおもうのですが?
本当にex01.exeのあるフォルダにいますか?

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:40
by のん
実行できました!!が、プログラムが終わらないのですが・・・。コードは
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[/url]) {
	FILE *fp;
	char str[80];

	if(argc !=2) {
		printf("ふぁいる名を指定\n");
		return 1;
	}

	if((fp =fopen(argv[1],"w")) == NULL) {
		printf("ファイルを開けません\n");
		return 1;
	}

	printf("終了するには空白行入力\n");
	do{
		printf(": ");
		gets(str);
		if(*str !='\n'){
			fputs(str,fp);
		}
	}while(*str !='\n');

	fclose(fp);

	return 0;
}
いきなり、終了するには空白行入力とでて、適当にaaaと入力してENTERをおしたのですが、入力がつづきますね。どういうことでしょう?

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:41
by のん
テキストファイルはできているのですが、何も書き込まれていませんでした。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:43
by miyaza
> いきなり、終了するには空白行入力とでて、適当にaaaと入力してENTERをおしたのですが、入力がつづきますね。
何も入力しないでENTERを押して下さい。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:46
by miyaza
このプログラムは何も入力されていない行が出るまで繰り返されます。
だからaaaといれてENTERをおしても終了しません。終了するにはもう一度何も入力しないでENTERを押して下さい。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:48
by のん
>何も入力しないでENTERを押して下さい。

やってみました。が : がでてくるだけで終わらないですね。

そもそもこのコードだとファイル名の指定ってでてこなくていいのですか?

ファイル名の指定→終了には空白行入力→文字入力してENTERだと思うのですが。
どこかコードがおかしいのかな?

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:51
by のん
>このプログラムは何も入力されていない行が出るまで繰り返されます。
>だからaaaといれてENTERをおしても終了しません。終了するにはもう一度何も入力しないでENTERを押して下>さい。

なにも入力しないでENTERを押しても:がでてきて終わらないです。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:56
by miyaza
2007/03/26(月) 20:26 のコードと変わっていないと勝手に勘違いしました。すいません。
2007/03/26(月) 20:26 のコードみたいにstrcat(str, "\n");をgets(str)の下に追加すれば大丈夫です。

Re:ファイル入出力

Posted: 2007年3月27日(火) 10:59
by のん
できました!!
strcat(str, "\n");はなんで'\n'にしないのですかね??

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:02
by miyaza
strcat(char *s1, const char *s2);
と定義されており、文字列1に文字列2を連結します。あくまで文字列です。だから"\n"とします。'\n'だと文字コードです。

gets()というのは一行読み取り末尾の改行文字を'\0'に置き換えます。だから改行が読み取れず無限ループに陥ってしまったわけです。

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:04
by のん
miyaza さんありごあとうございます!!

ところでまったく違う質問なのですが、miyazaさんはC言語勉強して結構長いのですか?また、仕事などでやっていたのですか? 差し支えなければお聞かせください。

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:07
by miyaza
>ところでまったく違う質問なのですが、miyazaさんはC言語勉強して結構長いのですか?また、仕事などでやっていたのですか? 差し支えなければお聞かせください。

そんなに長くありませんね。仕事はしていませんね、というかまだ高校生です。

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:12
by のん
そんなに長くありませんね。仕事はしていませんね、というかまだ高校生です。

ウソ!!!!なんでそんなに理解してるの?ちょ~頭いいですね?
私なんか1ヶ月やってても理解してるのかしてないのかというところです・・・。

具体的に良い勉強方法などありますか?

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:21
by miyaza
>具体的に良い勉強方法などありますか?
良い勉強方法は分かりません。ごめんなさい。

アドバイスでなくて申し訳ないんですが、私はあまり本を読んでいません。基本的にHPを見て学んでいます。
そこに書いてあることを片っ端からやっていくだけです。

Re:ファイル入出力

Posted: 2007年3月27日(火) 11:23
by のん
miyazaさんすごいですね!!やっぱり頭がいいんだ!!

チャットみたいなものを作りたいんですが・・

Posted: 2007年4月15日(日) 21:45
by やま
初めての書き込みです。
c言語は勉強して1年ほどです・・・・
質問なんですが僕もチャットみたいなものを作りたいんですが、作り方がさっぱりわかりません・・
どこか参考になるサイトがあったら教えてくださいm(__)m

Re:チャットみたいなものを作りたいんですが・・

Posted: 2007年4月15日(日) 22:22
by 管理人
このサイトで何度も紹介している、DXライブラリはご存知でしょうか?
私の過去のアプリ紹介で、
http://dixq.net/sakuhin.html
紹介していますけど、チャットも作った事あります。
DXライブラリを使った事があれば簡単ですよ^^

サンプルプログラムにまんま、プログラムがあるので

http://homepage2.nifty.com/natupaji/DxL ... m.html#N21

参考にしてみてください☆
突然みても何がなんだかわからない場合は、一つ一つわからない関数をリファンスで確認しながら見ていくといいですよ。

DXライブラリというものをご存じなかったらトップページからみていってください。

http://homepage2.nifty.com/natupaji/DxLib/

Re:チャットみたいなものを作りたいんですが・・

Posted: 2007年4月15日(日) 22:37
by やま
ありがとうございます!
DXライブラリは今、文字を表示できるぐらいです・・
サーバーが必要だと思いますが、もしもオンラインチャット的なものを
作ろうとしたらDXライブラリで作ることはできますか?

Re:チャットみたいなものを作りたいんですが・・

Posted: 2007年4月15日(日) 22:59
by 管理人
チャットって全部オンラインじゃないですか?^^;
おっしゃっているのは、IPアドレス知っている特定の相手とだけでなく、ソフトをもっていたらあらゆる知らない人とでもチャットが出来るようなシステムということでしょうか?

チャットシステムには詳しくないのですが、
固定IPアドレスがあればサーバーがなくても出来るんじゃないですか?
自分のパソコンを常につけっぱなしにして、起動したら自分のPCに接続するようにします。
そこでドンドン接続を増やしていけばいいのではないでしょうか。

Re:チャットみたいなものを作りたいんですが・・

Posted: 2007年4月15日(日) 23:19
by やま
そうなんですか・・
ありがとうございました。