C言語関係掲示板

過去ログ

No.100.Windowsでの「CTRL+Z」


はじめまして。がんばって一人でやっていても、書籍の意味合いや説明してくだ
さっているところが、詰まっています。どうかよろしくお願いします。
15−2の構造体の演習問題なのですが、以前から「CTRL+Z」のことは、よく
ここでも掲示板で見かけていたのですが、いざ今回の演習問題ではどこに回避
方法を入れればよいかと。アドバイスを、お願いいたします。


初めまして、ホームページ見てくださってありがとうございます。

>15−2の構造体の演習問題なのですが、以前から「CTRL+Z」のことは、よく
>ここでも掲示板で見かけていたのですが、いざ今回の演習問題ではどこに回避
>方法を入れればよいかと。アドバイスを、お願いいたします。

この件はまだ過去ログにはまとめていないのですが、
この掲示板の「表示設定」(広告の下にあります)で、「設定」を「全て」
にすると、下のほうに「No.338 BCBやVC++での「CTRL+Z」入力」というのが
あるので、そちらを参照してください。

要は、whileループを抜けたところで、
 (void)getchar();
を追加すれば回避できると言うことです。

こういった問題はなかなか、難しいですよね。


>下のほうに「No.338 BCBやVC++での「CTRL+Z」入力」というのが
>あるので、そちらを参照してください。
>要は、whileループを抜けたところで、
> (void)getchar();
>を追加すれば回避できると言うことです。

こんばんは。せっかくアドバイスを頂いたのですが
whileループを抜けた直後、表示前のfor文の一つ前に(void)getchar();
としても、答えは同じでした。CTR+Zを2回しないと、表示がされず。
何かVC++は違うのでしょうか?


今晩は。

>whileループを抜けた直後、表示前のfor文の一つ前に(void)getchar();
>としても、答えは同じでした。CTR+Zを2回しないと、表示がされず。
>何かVC++は違うのでしょうか?

getcharに入力しないといけないので、
CTRL+ZのあとにEnterキーを入力しないと上手くいかないようですね。
Enterキーを入力してみてください。


ども。


いろいろ試してみたところ、Ctrl-Zのあとに、とにかく画面上に改行を出力
すればいいようです。その改行(までのすべてのバッファの内容)は無視されて
その後はうまくいくようです。
# とりあえず、Ctrl-Zを読んだ後にputchar('\n')でOKでした

でも、何でそれでいいのか、本当にそれでいいのか、裏で何をやっているのかは
調べがつきませんでした。。

入力をファイルからのリダイレクトで行ったり、出力をファイルへリダイレクト
したりした場合は問題ありませんでした。また、デバッガでステップ実行した
場合も問題なく動作しました。

Win32では、コンソールのバッファにかなり手が出せるようなので、Ctrl-Zの
処理もいろいろやっているのでは、と思いました(Ctrl-Zが、入力しても
表示されないことからも考えて)。

コンパイラは関係ないようです。たぶん。
# 実装にかかわる部分なのでなんともいえませんが

やっぱり、Windowsの宿命なのでしょうかねー。。


では。


># とりあえず、Ctrl-Zを読んだ後にputchar('\n')でOKでした
>でも、何でそれでいいのか、本当にそれでいいのか、裏で何をやっているのかは
>調べがつきませんでした。。

こんばんは。実際にソースのどの部分に挿入なされたのでしょうか?
ともじさんからもアドバイスを頂いたのですが、上手くいかずに・・・
恥ずかしい知識不足で申し訳ありません。


>getcharに入力しないといけないので、
>CTRL+ZのあとにEnterキーを入力しないと上手くいかないようですね。
>Enterキーを入力してみてください。

こんばんは。私の力不足かもしれませんが、Enterキーを押しても
2回目のCTR+Zでないと、最終な一覧表示がでてきません。
ソースのどの部分に書かれると、実際に上手くいかれたのでしょか?


/*
        Ctrl+Zの処理について簡単にまとめてみました。
*/
#include <stdio.h>

int main(void)
{
        int a;
        int i;
        
        while(scanf("%d", &a) != EOF) {}
        /*puts("");/* 書き方はなんでも良いので改行 */
        printf("%d", a);
        printf("%d", a);
        printf("%d", a);
        /* 改行しない限り表示されない */
        
        return 0;
}
/*
        いろいろ考えた結果ですが、処理系によって
        Ctrl+Z > Enter('\n') でループから出るものと
        Ctrl+Z のみでループから出るものがあって
        後者の場合、scanf() 入力での最後の Enter('\n') が
        入力されていない結果、問題が起きるんだと思います。
*/


その後一人でさらに考えてみました。
よかったら参考にしてださいませ。

/* Ctrl+Z (EOF [End of File])の入力方式

LSI-C の場合
Ctrl+Z (EOF)を入力すると、画面上に ^Z が表示される。
改行('\n') を入力すると、stdin の終了(入力バッファをフラッシュする)

BCC の場合
Ctrl+Z を入力すると、画面上に ^Z が表示さず、改行しなくても
stdin の終了(改行しないと入力バッファをフラッシュしない)

・・・なぜか?
EOF周辺がたぶんこんな感じになってるからかな?

・・・適当な文字列・・・・・・あいうえをかきくけこままままままま<改行>
ファイル終わり>[EOF]もうファイルが終わっているよ〜〜〜。<改行>
ここからまた新しく始めよう([EOF]から改行まで無視されちゃったけど)<改行>
・・・・・・つづく・・・・
*/


ども。


>その後一人でさらに考えてみました。
>よかったら参考にしてださいませ。

おなじく。
でも、とくになにもわかりませんでしたが。。

どうも入力自体はうまくいっているようです。問題はCtrl-Zを入力した後で
標準出力がおかしくなる点ですね。^Zが表示されないとか、改行なしで
取り込めるとかは仕様といえなくもないですが。

VCにしろBCCにしろWindowsのコンソールをデフォルトのまま使っている
ようなので、コンパイラ自体は問題ないと思います。

以下に、試したコードをのせときます。Windowsのコンソールに関していじって
みました。コンソールまわりのWin32APIを調べていろいろやってみてください。。

#include <stdio.h>

#define WIN_CONSOLE 0

#if WIN_CONSOLE
#include <windows.h>
#endif

int main( void )
{
        int c;

#if WIN_CONSOLE
        HANDLE handle;
        DWORD mode;

        handle = GetStdHandle( STD_INPUT_HANDLE );
        GetConsoleMode( handle, &mode );
        mode &= ~ENABLE_PROCESSED_INPUT;
        SetConsoleMode( handle, mode );
#endif

        while( ( c = getchar() ) != EOF )
        {
                printf( "%x\n", c );
#if 1
                /* 改行読み飛ばし */
                getchar();
#endif
        }

#if 0
        printf( "\nc:%x\n", c );
#else
        printf( "c:%x\n", c );
#endif

        return ( 0 );
}

改行問題も含まれているので、問題の切り分けに注意してください。

他の解析アプローチとして、setvbuf()で自前のバッファを設定して監視する
というのもありますね。

いろいろかきましたが、「どうすれば^Z後の標準入力がまともになるか?」と
いう問題にたいしては、「^Z直後に改行を出力すれば、それ以後つかえる」と
いうのが今のところの(現実的な)答えでしょうか。どうしてなのかとか、
ほんとうにそれでいいのかとかはわかりませんが。。
# 仕様ないしバグと割り切るのもひとつの手でしょう。。


では。


この問題は以前質問をいただいたときに随分いじってみたのですが、
CTRL+Z入力後に一旦画面出力した表示を取り消しているようでした。
やはり、Windowsのショートカットキーの「CTRL+Z」(Undo)を
生かしているのではないでしょうか。

>いろいろかきましたが、「どうすれば^Z後の標準入力がまともになるか?」と
>いう問題にたいしては、「^Z直後に改行を出力すれば、それ以後つかえる」と
>いうのが今のところの(現実的な)答えでしょうか。

scanf("%c",・・・)やgetchar()の空読みのように、空出力が必要
ということなのでしょうね。


いろいろと本当にありがとうございました。
皆様に教えていただいたことを励みに、今一度自分でもチャレンジして
みます。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.01.11
Copyright(c) 2000-2002 TOMOJI All Rights Reserved