C言語でドラッグしたファイル名を表示する方法とは?

このQ&Aのポイント
  • C言語を学習中の方へ質問です。ドラッグしたファイルのファイル名を表示する方法について教えてください。
  • 参考書に記載されているfflush(stdin)の意味やgetchar()の役割がわかりません。教えていただけますか?
  • C言語のプログラムを実行するとキーボード入力を待つ処理が含まれているようですが、なぜgetchar()が必要なのでしょうか?
回答を見る
  • ベストアンサー

C言語 ドラッグとファイル名の表示

はじめまして。 C言語を学習しています。 PCのOSはWindows XPです。 ドラッグしたファイルのファイル名を表示する方法として参考書に例文が載っていますが、以下の部分が理解できません。 1、参考書に、「【fflush(stdin);】という記述は、出力バッファを強制出力する関数である fflush で、入力バッファである stdin をクリアしています。」との説明があります。 出力バッファの意味と入力バッファであるstdinについての説明が参考書に無く、ネットで調べましたが理解できる記事がありませんでした。 出力バッファの意味と入力バッファであるstdinの意味を教えてください。 2、【getchar();】は、実行されるとキーボードからの入力を待ち、エンターキーが押されると入力待ちを終了、入力したうちの1文字目を返り値として返す関数とのことですが、下記のプログラムでどのような役割をしているのか教えてください(下記のプログラムになぜgetchar関数が必要なのかがわかりません)。 なにとぞ、よろしくお願い致します。 ●参考書の例文 次のプログラムは、プログラム実行画面(コマンドプロンプトのような黒い画面)にデスクトップ等のファイルをドラッグし、そのファイル名を表示する例です。 #include <stdio.h> int main(int argc,char *argv[]) { if (argc > 1) { printf("%s\n",argv[1]); } fflush(stdin); getchar(); return 0; }

  • 501xx
  • お礼率90% (398/439)

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

(1) stdinは「標準入力」 stdoutは「標準出力」を stdio.h の関数で使うためのFILE *型の変数です。 printf("A") と fprintf(stdout, "A") が同じ動作になります。 通常は、stdinはキーボードからの入力に、stdoutは画面への出力に割り当てられています。 そのため、初級の入門書では getchar等の標準入力から入力する関数を「キーボードから入力」, printf等の標準出力に出力する関数を「画面へ出力」と記述しているケースがあります。 詳しくは「標準入出力」で検索。 ファイル入出力には、「バッファ」と呼ばれる一時記憶領域があります。 fputchar(c,fp) ; としても、その瞬間にファイルに書き込まれるのではなく、一旦バッファに保存されます。 バッファが一杯になる、(行バッファの場合)改行になる、といったタイミングで、ファイルに書き込まれます。(そして、バッファはクリアされます) また、入力時には、ある程度まとめて読み出します。 printf等の出力先である標準出力stdout、scanf等の入力先であるstdinも同様、ファイル扱いになり、バッファリングされることがあります。 より詳しくは「ファイル バッファリング」で検索。 fflushは、上記のようなバッファに溜ったデータを、従来の書き出しタイミングを無視して、強制的に書き出して、クリアするものです。 **** stdinのような「入力」に対して使った場合、どうなるか決まっていません **** http://www.kijineko.co.jp/tech/superstitions/fflush-with-input-stream.html ただ、Visual Cでは、独自の仕様として、「入力バッファのクリア」になります。 他のC言語では使えないので、注意してください。 (2) Windowsのコンソール用アプリケーションを、ダブルクリックやドラッグ&ドロップで実行したとき、コマンドプロンプトみたいなウィンドウが出て実行が始まり、終了と同時に閉じます。 一瞬で終わるプログラムだと、画面に表示された内容を読むのは無理です。 その対策の一つとして 「プログラム終了直前にキー入力を待って、入力があったら終了する」 というものです。入力があるまでは実行中なので、ウィンドウは閉じません。 キー入力待ちの方法はいくつかありますが、その一つがgetchar()を使うものです。 このときstdinのバッファになにか入っていると、キー入力を待たずにバッファから読み込んでしまうので、その前にバッファをクリアしておく、というのがこの部分の意図です。 ちなみに、このプログラムは「コマンドラインの第1引数を出力する」プログラムです。 ドラッグ&ドロップで実行すると、コマンドライン引数にそのファイルを指定した状態で実行される、というWIndowsの動作を利用しています。 「ファイルをドラッグし、そのファイル名を表示する」というのは正確ではありません。 標準入出力とかバッファリングの説明が無い(または不十分)というのは、C言語の勉強用としては問題有りだと思います。 他の参考書も買って、併用する(あるいは、今の本は捨てる)ことを強くお勧めします。 他の参考書は、Visual Stdioに特化していない物がいいです。

501xx
質問者

お礼

ご回答いただき、ありがとうございました。

その他の回答 (2)

  • wormhole
  • ベストアンサー率28% (1620/5655)
回答No.3

とりあえず参考書を読むときは使用されてる開発環境のライブラリのマニュアルも一緒に読まれる方がいいと思います。 1. stdinは、Cのランタイムライブラリが標準入力に対して自動でfopen()してくれてるものです(なのでstdinの型はFILE *)。またバッファリング機能はありますがそれはstdin(というより"r"でfopen()されたもの)の一機能であって、stdin=入力バッファというわけではありません。 fflush()でフラッシュされるバッファというのは"w"などでfopen()されたストリームが持ってるバッファの事です。fflush(stdin)についてはどう処理されるかは決められてませんので処理系により異なります。またCのランタイムライブラリが標準出力に対して自動的にfopen()しているものがstdoutになります。 ちなみにstdinやstdoutは知らず知らずによく使ってると思いますよ。 getchar() getc(stdin)の省略形 scanf(~) fscanf(stdin,~)の省略形 printf(~) fprintf(stdout,~)の省略形 それとOSがバッファリングの内容を自動的に処理するということはないです。 2. #1の方の説明の通り。

501xx
質問者

お礼

ご回答いただき、ありがとうございました。

  • koakino
  • ベストアンサー率44% (22/50)
回答No.1

1. バッファとは、文字などのデータを一時的に蓄えておく場所です。 printfやputsなどを使うと、標準出力(stdout)と呼ばれるバッファに文字列が送られます。 そうしておくとOSなどが勝手にバッファから文字列を取り出して、画面に出力してくれる仕組みです。 なぜバッファを使うのかというのはハードウェアの話になりますが、端的に言うとその方が効率が良いからです。 プログラムから見て、外に出力するためのバッファを出力バッファ。 逆に外からの入力を受け取るためのバッファを入力バッファと言います。 先ほどの標準出力はその名の通り出力バッファで、stdin(標準入力)は入力バッファです。 ちなみにstdinはキーボードからの入力を蓄えるバッファです。 fflushはバッファをフラッシュする関数です。 最初にOSなどが勝手にバッファから文字列を取り出すと言いましたが、これをプログラム側から強制的にやらせるための関数です。 これを入力バッファに対して使うと、溜まっているデータを捨てることになります。 参考書の記述は、「【fflush(stdin);】という記述は、バッファを強制フラッシュする関数である fflush で、入力バッファである stdin をクリアしています。」という意味だと思います。 2. ユーザがエンターキーを押すのを待つためにあります。 プログラムの動作には不要なものですが、入門書ではよく使われるテクニックです。 Windowsなどの環境では、通常プログラム実行画面(コマンドプロンプトのような黒い画面)はプログラムが終了すると勝手に閉じてしまいます。 初心者の方はそこでつまづくことが多いので、getcharを入れて待つようにしてあります。 それだけの役割なので、自分でプログラムを書くときは入れなくても問題ありません。

501xx
質問者

お礼

ご回答いただき、ありがとうございました。

関連するQ&A

  • C言語 複数指定したファイルの内容表示

    C言語の質問です。 「実行したファイル名を除いたコマンド ライン引数に、 複数個指定したすべてのファイルの内容を標準出力に表示する」 というプログラムを作成しようと思うのですが。。。 どうしても上手くいきません。 1つのファイルの内容を標準出力に表示するプログラムになってしまいます。 どなたかお力を貸してください。 ちなみに、私が作成したプログラムは、以下です。↓↓ #include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; int c; if(argc != 2) { return 1; } if((fp=fopen(argv[1], "r"))==NULL) { return 1; } while((c=fgetc(fp)) !=EOF) { fputc(c, stdout); } fclose(fp); return 0; }

  • C言語でコマンドラインの引数について。

    コマンドラインで引数をわたす基本的なプログラムは main(int argc,char *argv[]){....] ですよね。 今回実行時に、 >実行ファイル名 123 + 233 といれたら、123+233を計算してくれるプログラムを作ろうとしています。 その場合、main(int argc,int *argv[]){} としたら、argv[1]に123が入って、argv[2]に+が入って、argv[3]に233が、入るというわけではないんでしょうか? とりあえず、確認で #include<stdio.h> main(int argc,int *argv[]) { printf("%d\n%d\n",argv[1],argv[3]); } としてみたんですが、実行結果は、とても長い数字がでてきてきました。 なにがいけないのか教えてください。 お願いします。 あとWindows MEでVC++6を使ってます。

  • CUIプログラムにドラッグして1度に複数の変換は?

    みなさま、こんにちは。 Visual c++2010Express-Cを用いて、C言語のプログラムを作成しています。CUIのプログラムで、作成されたexeにファイルをドラッグしてファイルの変換をするプログラムです。 main.c の始まりは int main(int argc, char *argv[]) です。 ココで問題があるのですが、作成されたexeには1つのファイルをドラッグすることでしか変換出来ない、つまり1度のドラッグで1つのファイルしか変換出来ません。 現在、400ファイル程あるのですが、400回もドラッグをするのは果てしなく苦痛です。 int main(int argc, char *argv[]) 上記を変更して、複数のファイルを選択して1度のexeへのドラッグで変換出来ないものでしょうか? もしくは違った方法がありますでしょうか? どなたかお分かりになりましたら、ご教示願えないでしょうか? お手数をおかけ致しますが、よろしくお願いいたします。

  • C言語のシェルプログラミングの課題が分かりません。

    C言語のシェルプログラミングを作れという課題で、以下のように作ったんですが、実行して何度かコマンドを入力した後、exitによって一発で終わらせることができません。どのように書き換えればいいか教えて下さい。 また、他にも書き換えた方がよいと思えるところがあったら是非教えて下さいm(_ _)m #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #include MAX_ARGS 10 #include MAX_LEN 100 extern char **environ; void child(int argc, char *argv[MAX_ARGS]); int main(void){ int argc, n = 0; int status; char input[MAX_LEN], *argv[MAX_ARGS], *cp; const char *delim = "\t\n"; while (1){ ++n; printf("$ "); fflush(stdout); if(fgets(input, sizeof(input), stdin) == NULL){ break; } cp = input; for(argc = 0; argc < MAX_ARGS; argc++){ if((argv[argc] = strtok(cp, delim)) == NULL) break; cp = NULL; } if(strcmp(argv[0], "exit") == 0){ exit(0); } pid_t pid = fork(); if(pid == -1){ perror("fork"); exit(1); }else if(pid == 0){ child(argc, argv); }else{ wait(&status); } } return 0; } void child(int argc, char *argv[MAX_ARGS]{ execvp(argv[0], argv); }

  • 標準関数 getchar( ) の動作について

    getchar()の動作がよくわかりません。 以下のコードでバッファに'\n'が残ってしまっていて?その'\n'が読み込まれている事まで解りました。 どのようにすればキーボードから入力を受け付けるようになりますか? よろしくお願いいたします。 #include <stdio.h> int main(int argc, char *argv[]) {   int iDataA = 0;   int iDataB = 0;   /* キーボードから文字を入力 */   iDataA = getchar();  /* <-- 'a'を入力しエンター */   iDataB = getchar();  /* <-- キーボードからの入力を受け付けません */  return 0; }

  • fflush()、setbuf()について

    C言語にお詳しい方、ご回答お願いします。 fflush関数は、「バッファに格納されているデータを吐き出す。」とあるのですが、具体的にどのような動作をするのでしょうか? (1)fflush(stdin),fflush(stdout)とそれぞれ記述するとどのような動作をするのか。 (2)データをフラッシュしたいときとは、具体的にどんなときか。(scanfなどで続けてデータの入力を行うこと以外に) setbuf関数は、「出力バッファをユーザバッファに指定」とあるのですが、具体的にどういう意味なのでしょうか? (1)setbuf(stdout,buf)、setbuf(stdin,buf)とそれぞれ記述するとどのような動作をするのか。 よろしくお願いします。

  • fflush(stdin)の使い方とprintf()関数getchar()関数の違いについて

    はじめまして。 現在c++を勉強し始めて1週間の初心者です。 fflush(stdin)について質問です。下記のプログラムで小文字入力したアルファベット1文字を大文字に変換して出力しています。方法(1)ではgetchar()関数とputchar()関数を使用していますがどうしてこの場合にはfflush(stdin)が必要となり、方法(2)のprintf()関数とscanf()関数を使用した場合はfflush(stdin)が必要ないのでしょうか?どなたか私のような初心者でも分かるように詳しく説明してもらいたいです。 何故かプログラムを書いているとprintf()とscanf()がよく混乱します。原因として、printf()を先に書く場合と、scanf()を先に書く場合が有るからだと思っているのですが、まだよく理屈の理解ができません。なので出来ればこれらの関数についても基本的な概念を教えていただきたいです。それと方法(2)では何故最後にscanf(%c):が無くても良いのかも良く理解できません。 どなたか是非とも回答宜しくお願いします。 #include <stdio> main void() { 方法(1) printf("\n文字を1つ入力してください:"); fflush(stdin);    char ch=getchar(); ch=ch-32; putchar(ch);    方法(2) printf("\n文字を1つ入力してください:") //fflush(stdin);必要なし???    char ch; scanf("%c",&ch); ch=ch-32; printf("%c",ch);    //scanf(%c):??? }

  • ちょっとした疑問なんですが・・・(C言語)

    何度も質問してごめんなさい! ちょっとした疑問なんですが、下記のプログラム中の、 while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } のコードで、「while(!feof(in))」でストリーム「in」結び付けられているファイルの終わりに達していれば繰り返し処理を終えるのは分かるのですが、 なぜ、インクリメントも無くファイルの終わりまで文字を調べ進めることができるのでしょうか? 未熟者の私ですが教えて頂けないでしょうか? 【プログラム例】 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *in, *out; unsigned char ch; if(argc!=3) { printf("使用法: <プログラム名> <入力ファイル名> " "<出力ファイル名>\n"); exit(1); } if((in = fopen(argv[1], "rb"))==NULL) { printf("入力ファイルを開くことができません\n"); exit(1); } if((out = fopen(argv[2], "wb"))==NULL) { printf("出力ファイルを開くことができません\n"); exit(1); } while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } fclose(in); fclose(out); return 0; }

  • C言語、ファイル操作、fgets()について

    次のプログラムは入力された行を読み込み、コマンドラインで指定されたファイルに書き込みます。 空白行が入力されたら、入力の終了とみなしてファイルを閉じます。続いてファイルを入力用に開き、 fgets()を使ってファイルの内容を表示するものです。 (ソースコードが長くてすみません) #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fp; char str[80]; /* コマンドライン引数を検査する */ if(argc!=2) { printf("ファイル名を指定してください\n"); exit(1); } /* 出力用にファイルを開く */ if((fp = fopen(argv[1], "w"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } printf("終了するには空白行を入力してください\n"); do { printf(": "); gets(str); strcat(str, "\n"); /* 改行を追加する */ if(*str != '\n') fputs(str, fp); } while(*str != '\n'); fclose(fp); /* 入力用にファイルを開く */ if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } /* ファイルを読み込み直す */ do { fgets(str, 79, fp); if(!feof(fp)) printf(str); } while(!feof(fp)); fclose(fp); return 0; } 【質問】fgets()内のint型の数値「79」がどうして79なのかが分かりません。     80でも良いような気がするのですが・・・

  • C言語のファイル処理について

    環境 OS:Windows VISTA Ultimate コンパイラ:Borland C++ Compiler 5.5 Cの基礎的な勉強をしています。2つほど質問があります。 1つ目は、ファイル処理の勉強としてプログラムを作っているのですがファイルが上手く開けません。プログラムとしてはファイルを開いて、ファイル内に記述されている数値を取り出し、計算を行う簡単なものを作っています。ソースは以下のものになります。 #define N 256 int file_read(char filename[] , int count[]) { int m; FILE *fp; fp=fopen(filename,"r"); if(fp==NULL) { /* オープン失敗 */ printf("Not Found File\n"); return -1; /* 戻り値-1 */ } while((m = fgetc(fp)) != EOF) { 読み取った数値配列に格納する処理 } fclose(fp); return 0; } int operation(int count[]) { 計算処理 return 0; } int main(void) { int *count[N]; char *filename[256]; memset(count, 0, sizeof(count)); /* 変数・配列初期化 */ printf("Please Input Filename:"); fgets(filename, sizeof(filename), stdin ); if(file_read(filename,count) != -1) operation(count); return 0; }  バッファオーバーランの事を考え、fgetsによるキー入力にしたのですがファイルオープン失敗になってしまいます。fgetsのあと、変数filenameの中身を確認したところ、キー入力した文字はきちんと代入されていました。オープンするファイルはきちんとあるのですが・・。  fgetsをscanfに変えた場合は上手くいくので書式指定をしてscanfを使えばいいのでしょうが、なぜfgetsで上手くいかないでしょうか? 2つ目はgetchar()とfgets()に関してです。 while((c = getchar()) != EOF) { . .処理 . fgets(変数, sizeof(変数), stdin ); . .処理 . } とした場合、fgetsの処理が無視されてしまいます。 これはどういったことが原因なのでしょうか。 ご教授、お願いいたします。

専門家に質問してみよう