こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

意味のよく分らないソース

http://oshiete1.goo.ne.jp/qa2846277.html
上のURLのソースについていくつか質問です。

while(!feof(stdin)) {
scanf("%c", &ch);
if(!feof(stdin)) printf("%c", ch);
}

と、書いてありますが、「!feof(stdin)」のようにいきなりエクスクラメーションマー

ク(ビックリマーク)が付いていますが、これはどの様な意味になるのでしょうか?
また、whileでstdinを回しているようですが、stdinはどのタイミングにどの様に入力し

ているのでしょうか?

ANo.4の方がcp.exeというファイル名でこのプログラムをコンパイルしたら、「cp <

infile.txt > outfile.txt」と入力すると、infile.txtの内容をoutfile.txtへコピーで

きると書いてあるのですが「<■■■■■>」のように「<」と「>」のマークでくくって

いるのはどういう意味になるのでしょうか?

投稿日時 - 2008-07-13 04:11:57

QNo.4172405

困ってます

このQ&Aは役に立ちましたか?

20人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

#5です。

> 記述した内容を読み取ったかどうかはどの様にして判定しているのでしょうか?

それはscanf関数の内部仕様に関することで、
私にはわかりません。

投稿日時 - 2008-07-14 23:12:54

お礼

そうですか、解答有り難うございました。

投稿日時 - 2008-07-15 01:19:36

ANo.5

#3です。
> 何を判断して入力終了
書式文字列に記述した内容を読み取ったときです。

> Enter Keyを押すと、'\n'のあとに、EOFでも付いているのでしょうか?
付いていません。
Windowsの場合であれば、Ctrl+ZでもってEOFとみなします。

投稿日時 - 2008-07-14 20:22:28

お礼

>書式文字列に記述した内容を読み取ったときです。
記述した内容を読み取ったかどうかはどの様にして判定しているのでしょうか?

投稿日時 - 2008-07-14 21:02:51

ANo.4

一応No.2に補足しておきますが、Cの真偽値は真(非0)と偽(0)です。つまり-1でも2でも0ではないので真になります。
たとえばif(feof(stdin))の意味はif(feof(stdin)==1)では間違っており、if(feof(stdin)!=0)が正しい解釈になります。
#実はfeof()がEOFを発見したときに返る値は実装依存なので、前者で書くとEOFを判定できずに思わぬ不具合を引き起こす可能性があります

今回の質問とは直接関係のない蛇足ですが、参考までに。

投稿日時 - 2008-07-13 23:41:05

お礼

なるほど、解答有り難うございます

投稿日時 - 2008-07-13 23:59:24

ANo.3

> scanfって改行されるまで入力される関数
そういうことではありません。scanf()は必ずしも改行(Enterキー)を求めてはいません。

入力元がたまたま標準入力だったら、Enterキーを押すことで
「入力が終わったよ」という印となる、というだけです。

表現を変えると、入力元がたまたま標準入力だったら、
Enterキーを押さないと「入力が終わったよ」という印がわからない、
というだけです。

投稿日時 - 2008-07-13 07:00:31

お礼

解答有り難うございます。

では、scanfは、改行を判断材料にしているのではないとすれば、何を判断して入力終了としているのでしょうか?
通常のキーボードからの入力の際は、Enter Keyを押すと、'\n'のあとに、EOFでも付いているのでしょうか?

投稿日時 - 2008-07-13 15:20:01

ANo.2

> ということは、whileやifのように真偽判定をするもので「!x」だけのようになっていたら、「x==0」という意味になるということですか?

!は論理式の否定(NOT)を表す記号です。したがって、xが0(偽)の時!xは1(真)となります。!は論理演算子なので、ifやwhileの中だけではなくて、論理式が書けるところならどこにでも書けます。!feof(stdin)と言う論理式は、feof(stdin)が0のときに真となるので、feof(stdin)==0と同じ意味になります。

> コピー元ファイル名を< >でくくって入力しないとコピーできないのですが、< >ってどういう意味を持っているのでしょうか?

これは、ファイル名を<>でくくっているのではありません。<、>はリダイレクトの記号で、<ファイル名はstdinをファイルにリダイレクトし、>ファイル名はstdoutをこのファイルにリダイレクトします。
詳しくはANo.1さんの示されたURL先に説明があります。

投稿日時 - 2008-07-13 05:56:18

お礼

解答有り難うございます。

なるほど、feofは、入力の終わりが来たら真(1)を返すから、ここではfeofが入力の終わりで真を返した際に、whileを終わらせるために!feofとして入力の終わりで偽を返すようにしていたということですか。

そんで、「cp < infile.txt > outfile.txt」は、「<infile.txt」と「>outfile.txt」で一括りということだったんですね。

投稿日時 - 2008-07-13 15:17:10

ANo.1

!feof(stdin)は、feof(stdin)==0と言う意味ですね。
feofはstdinが終りにこれば
stdinという標準入力の終りが来ない限りループを続けるという意味です。
標準入力がコンソールであるならCtrl+Cが押されればそこが終わりとなります。

stdinの処理されるタイミングですが、標準入力がコンソールであれば
初めてscanfが呼び出された時点で入力待機します。その後コンソールで改行が押されたら開業まで処理をします。
Hellow, world![改行]
と改行されれば、そこまでループをまわして文字を読み込んでそのまま出力します。
読み込む文字がなくなったら、またscanfのところで待機します。
これをCtrl+Cなどで終わりであることを指示されるまでループさせます。

標準入力stdinがファイルである場合は、もっと単純でファイルの終端が車で
ファイルの中の文字を読み込んで出力することを繰り返します。

stdin、stdoutはそのソースのページの回答に詳しいものがあります。

feofはこのあたり
http://www9.plala.or.jp/sgwr-t/lib/feof.html

リダイレクトはこのあたり
http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231093/

投稿日時 - 2008-07-13 04:33:16

お礼

>!feof(stdin)は、feof(stdin)==0と言う意味
ということは、whileやifのように真偽判定をするもので「!x」だけのようになっていたら、「x==0」という意味になるということですか?

>ファイルの終端が車でファイルの中の文字を読み込んで出力することを繰り返します。
scanfって改行されるまで入力される関数なので、入力されたファイルの一番最後の行に改行が入ってなかったら、最後の行が入力されない気がするのですが、実際にはきちんとコピーされています。これはいったいどういうことなのでしょうか?


後、コマンドラインでファイルをコピーすることに使う場合、http://oshiete1.goo.ne.jp/qa2846277.htmlのANo.4の人が示しているように、コピー元ファイル名を< >でくくって入力しないとコピーできないのですが、< >ってどういう意味を持っているのでしょうか?

投稿日時 - 2008-07-13 05:41:12