ここから質問投稿すると、最大10000ポイント当たる!!!! >>

RedHatLinux7J環境でC言語のプログラミングを行っています。キーボードからCTRL+D(EOF)が入力されるまで、1文字入力しその文字コードを出力するプログラムです。
しかし、CTRL+Dを2回押さないと処理が終わりません。
これはなぜなのでしょうか。ご存知の方いらっしゃいましたらお願いいたします。

#include<stdio.h>
main(){
int ch;

while((c=getchar())!=EOF)
printf("%d ",ch);

putchar('\n');
}

このQ&Aに関連する最新のQ&A

A 回答 (2件)

最初は「そんなことないだろう」と思ってたんですが,確かに入力行の途中でCtrl+Dを押したときは,リターンを押したときのようにそこまでの入力内容がフラッシュされるだけで,EOFにはならないですね.


[a],[b],[c],[Ctrl+D]と押した場合
 → abc97 98 99
私も知らなかったんですが,どうも行頭で押さないとCtrl+DはEOFにならないようです.
キーボードバッファリングの仕様がこうなってるからどうしようも無いと諦めるか,あるいはバッファリングをせずに直で1文字ずつ取るか,どっちかですね.
バッファリングをしないでキーボードから直接文字を取るにはcursesライブラリを使うのが簡単だと思います.

#include <stdio.h>
#include <curses.h>

main()
{
int ch ;

initscr();

while ( ( ch = getch() ) != 4 ){
printf("%d ",ch);
refresh();
}

printf("\n");
endwin();
}

4がCtrl+Dを表す文字コードです.initscr, getch, refresh, endwinがcursesのライブラリ関数です.

コンパイルのときはcursesライブラリをリンクするのを忘れないで下さい.gccの場合↓
gcc test.c -o test -lcurses
    • good
    • 0
この回答へのお礼

ありがとうございます!!
Windows環境だとちゃんといくのに、Linuxだと駄目で
非常に悩んでおりました。
cursesライブラリについては全く知らなかったので
色々勉強してみます。

またよろしくお願いします!!!

お礼日時:2003/05/22 23:58

Ctrl + Dで終了したいのですね。



#include <stdio.h>

main()
{
  int ch ;
  while ( ( ch = getch() ) != EOF ){
    printf("%d\n",ch);
  }
}

でいかがでしょうか。
getcharをgetchに変えただけです。
また、putchar('\n');もprintfに組み込んでしまいました。
もしかしたら
#include <conio.h>
を入れないとダメかもしれません。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Q画像の拡大・縮小

読み込んだ画像を1.5倍に拡大、2/3倍に縮小したいのですが、C言語でそのようなことは可能なのですか?また、できるとしたら、どのように行えばいいのでしょうか?教えてくださいm(_ _)m

Aベストアンサー

座標系だけでしたら処理は単純です。
単に倍率をかけてあげればよいだけです。

具体的な計算式は、
(1.5倍の例)
 Image( x*1.5, y*1.5 ) = Image( x, y )
ということです。

これだけでは多分わからないですね^_^;
以下にプログラムを書きます。

----------------------------------------------------------------

void main()
{
 unsinged char Image[ 16 ][ 16 ]; // 読み込んだ画像の格納場所
 unsinged char Image2[ 24 ][ 24 ]; // 拡大した画像の格納場所
 double zoom = 1.5;
 int x, y;
 int i, j;

/*
  画像の読み込み処理
*/

 for(x=0; x<16; x++)
 {
  for(y=0; y<16; y++)
  {
   // 拡大した時に隙間が空くので、その箇所を補完する
   for(i=0; (double)i<zoom; i++)
   {
    for(j=0; (double)j<zoom; j++)
    {
     Image2[ (int)(x*zoom)+i ][ (int)(y*zoom)+j ] = Image[ x ][ y ];
    }
   }
  }
 }
}

----------------------------------------------------------------

これでImage2に1.5倍した画像が格納されるはずです。
(注:Image2の配列のサイズは任意に決めています)

理解できたでしょうか。

画像の拡大縮小に関しては、まだ多くの手法が存在しますので、
調べてみると面白いかもしれませんよ(^_^)

座標系だけでしたら処理は単純です。
単に倍率をかけてあげればよいだけです。

具体的な計算式は、
(1.5倍の例)
 Image( x*1.5, y*1.5 ) = Image( x, y )
ということです。

これだけでは多分わからないですね^_^;
以下にプログラムを書きます。

----------------------------------------------------------------

void main()
{
 unsinged char Image[ 16 ][ 16 ]; // 読み込んだ画像の格納場所
 unsinged char Image2[ 24 ][ 24 ]; // 拡大した画像の格納場所
 double zoom = 1.5...続きを読む

Qfgets関数のEOFの扱い方について

fgets関数のEOFの扱い方って、
ファイルの終わり(EOF)を検出し、かつ配列に1文字も読み取れなかった場合、配列の内容を変化させずに残しNULLを返す。配列に1文字以上読み取れた場合、EOFをバッファに残し配列に'\0' を追加する。その後、EOFを読み取り終了。
であってますか?

Aベストアンサー

★回答者 No.1 です。追記。
・回答者 No.2、No.3 さんの通り『EOF』は『EOFコード(^Z)』をバッファに
 残すわけではありませんよ。→イメージ的には『あっている』のですよ。あくまで。
・厳密には、回答者 No.3 さんのアドバイスどおりです。
・つまり、『fgets』関数で1文字も読み取れなかった場合には、『ファイル終了』
 というフラグ情報をセットするのです。→EOFをバッファに残す感じですね。
・そのため、次に読み込んだ場合に、このフラグ情報を『EOF』として読み取って
 終了するわけです。→『fgetc』関数も同じ仕組みです。
・また、途中でエラーが発生した場合にも『fgets』関数は『NULL』を返します。
・この場合は、『エラー発生』のフラグ情報をセットしてから『NULL』を返すのです。
・よって『NULL』が返される多くの場合は、『ファイル終了』ですが、エラーが発生
 しても『NULL』が返されます。そこで、『feof』関数や、『ferror』関数でどちらか
 判定するわけです。feof(fp) や ferror(fp) で 0 以外が返されたら『ファイル終了』
 や『エラー発生』と判別します。→厳密にエラー発生の対策をする場合はね。
・あと、一度『エラー発生』のフラグがセットされると『fseek』関数などではその
 情報はクリアされません。→『clearerr』関数でクリアします。
・『ファイル終了』情報はファイル・ポインタの位置を変える『fseek』関数などで
 その情報がクリアされます。
・『ファイル終了』、『エラー発生』のフラグ情報などは、それぞれのファイル
 ポインタで管理されています。

最後に:
・イメージ的には、最後に『EOFを読み取り終了』という事になります。
・質問者さんは、プログラムや、テストプログラムを作って動作に疑問を持ったのですね。
 そうでないと、『EOF』を検出して、1文字も読み取れなかった場合、配列内容が変化
 しない事を推測できませんものね。
・そこで、最後にアドバイスします。
・疑問があったら簡単なテスト・プログラムを作ってみて確認することがとても大事ですよ。
 動作確認すると『fgets』関数などの仕組みをより理解できますから。
・以上。おわり。

★回答者 No.1 です。追記。
・回答者 No.2、No.3 さんの通り『EOF』は『EOFコード(^Z)』をバッファに
 残すわけではありませんよ。→イメージ的には『あっている』のですよ。あくまで。
・厳密には、回答者 No.3 さんのアドバイスどおりです。
・つまり、『fgets』関数で1文字も読み取れなかった場合には、『ファイル終了』
 というフラグ情報をセットするのです。→EOFをバッファに残す感じですね。
・そのため、次に読み込んだ場合に、このフラグ情報を『EOF』として読み取って
 終了するわけです。→『f...続きを読む

QC言語のプログラムが実行できません。

C言語のプログラムが実行できません。

コンパイルは出来るんですが、実行すると、「Segmentation fault」と表示されてしまいます。

これは何のエラーなんでしょうか?
基本的な事かもしれませんが、分かる方宜しくお願い致します。

Aベストアンサー

僕も何度も出したなぁ。

ひとくちにSegmentation faultといっても、それこそさまざまな要因があるので、
これだけで原因を突き止めるのは非常に難しいです。

コンパイルはあくまで文法としてみているだけであり、
処理の流れ、メモリ確保など、プログラムそのものを見ているわけではありません。
このエラーが出るのは文法などよりもっと上位の原因なのです。
たとえばですが。
長さ10の配列があったとして、11番目以降を参照したりすると、
そういうのが出たような気がします。

ですから、変数があれば、その内容をprintf文で逐一出していき、
変な値が入っていないとか、少しずつ直していくしかないと思います。

QコマンドプロンプトからのEOFの入力方法について

#include <stdio.h>

main(){
int cnt[10];
int c;
int i;
for(i=0; i<10; i++){
cnt[i] = 0;
}
while((c=getchar())!=EOF){
if(c>='0' && c<='9'){
cnt[c-'0']++;
}
}
for(i=0; i<10; i++){
printf("%d : %d", i, cnt[i]);
}
}

という、キーボードから入力した数値の個数を
表示するプログラムを、VisualC++で、Win32consoleアプリケーションで作ったのですが、
コマンドプロンプトから何個かの数値を入力したあと、Enterキーを押しても
何の反応もありません。
キーボードから「EOF」を入力するにはどうすればよいのでしょうか。
または、どういう状態をEOFと言うのでしょうか。

Aベストアンサー

くわしかないですが。
・Windowsのコマンドプロンプトでも^Zで入力終了です
#って違うことを訊いていたり?

・^ZはASCIIだと0x1aなのはその通りですが、getcharでそのキャラクタを
受け取るわけではありません。#3の回答にあるとおりです。
#(ストリームがバイナリの場合は別)

・テキストモードでファイルをオープンして読み込んでいる場合、
・・データの中に0x1aがあってそこに到達した
・・ファイルの終端に到達した
ときにEOFが返ってきます。

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

Qがあるのにsqrtが・・・

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined reference to `sqrt'
collect2: ld はステータス 1 で終了しました

ちなみにLinux(Fedora core 4)を使用しています。
初心者ということもありなぜエラーが出るのか分かりません。
ちなみに<math.h>を使用しないプログラムは普通に動作します。
解決方法をご存知の方がいらっしゃいましたらご教授下さいませ。
よろしくお願いします。

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined r...続きを読む

Aベストアンサー

コンパイルのオプションつけてないとかないですよね?
たとえばTerminalとかだとコンパイル時に 『-lm』とかつけますが

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。


人気Q&Aランキング