
http://oshiete1.goo.ne.jp/qa3853689.htmlにて質問した内容ですが、
想定していたソースの範囲内では解決しないことが分かりましたので、新規に立てさせていただきます。
下記でfgetsを使って入力した後についてですが、*2のgetcharを無視して、*1のscanfで入力を受け付けなくなります。
*2のgetscharについては、その個数を増やしても同様に無視されます。
これを解消する方法はないでしょうか?
ちなみにコンパイラはBBC、開発環境はVistaです。
なお、簡略のため#includeなどは省略しています。
#define SIZE 16384
void main(void){
int mode,r;
while(1){
do{
r = scanf("%d", &mode); //*1 return後に停止
while(getchar() != '\n'){ };
}while(r == 0)
switch(mode){ //その他選択肢あり
case 1:
execute();
break;
}
}
return;
}
void execute(void){
char moji[SIZE];
char buf[SIZE];
while(fgets(buf, sizeof(buf), stdin) != NULL){
if(sizeof(moji) < strlen(moji) + strlen(buf))
break;
strcat(moji, buf);
}
while(getchar() != EOF){ }
getchar(); //*2 これを無視して動作(scanfでも同様)
return;
}
No.4ベストアンサー
- 回答日時:
★フィルタ・コマンドですか。
・標準入力(stdin)でキーボードからの入力では必ず『改行』を含むように
注意するしかないような気がします。
・過去に MS-DOS 用のフィルタコマンドをよく作成しましたが fgets で
『改行』コードが最終行に追加されない場合を入力の終わりと判定する
スマートな方法はないです。低水準の関数を使って直接読み取るように
すれば可能ですが移植性も考え高水準の関数を使うべきです。
元々低水準関数は処理系が高水準を実現するために用意されているだけで
プログラマに利用するようには考えられていません。
・私の対策方法
最終行に改行コードがなくて『^Z』+『Enter』を押すとまだ入力待ちに
なるのためもう一度『^Z』+『Enter』を押して終わりと判定させるように
入力側(人間)が気をつけるようにしています。
※ほかにもっと良い方法があれば私も乗り換えたいです。
・OS(Windowsなど)限定で利用するならAPI関数を直接呼び出して fgets と
ほぼ同じ処理をする関数を自作すれば要求通りの動作が可能です。
あまりお勧めではありませんが方法としてはあります。
また conio.h の kbhit()、getch()関数を使って fgets 同等の関数を
作り出す方法もあります。こちらも処理系や OS によって conio.h が
用意されていない場合もありますので注意すべきです。
・さて、どうしますか?
暫定的には、入力画面やreadmeなどで注意を喚起し、あとは使用者に任せるしかありません。
ファイル入力への対応へ踏み切れれば、標準入力による入力方法を止め、ファイル入力のみに絞ることでエラーの発生を回避する方法を取りたいと思います。
まだ先の話ではありますが、将来的にはWin32 APIへ移行したいと思っているので、それまでは使用者に不便を強いるしかないかと。
長々と、ありがとうございました。
No.3
- 回答日時:
★難しそう。
>できればこの状態でも正常に動作するようにしたいのですが、可能でしょうか?
↑
feof()を使えば少しはマシになります。
// 実行
void execute( void )
{
char moji[ SIZE ] = { 0 };
char buff[ SIZE ] = { 0 };
//EOF(^Z)になるまで、文字列を受け取る
puts( "EOF(^Z)まで入力" );
while ( !feof(stdin) && (fgets(buff,sizeof(buff),stdin) != NULL) ){
if ( sizeof(moji) < (strlen(moji) + strlen(buff)) ) break;
strcat( moji, buff );
}
puts( "フラッシュ" );
while ( !feof(stdin) && (getchar() != EOF) ){
;
}
puts( "一時停止" );
getchar(); //*2 これを無視して動作
puts( "抜ける" );
}
これでも改行がない状態で^Zを入力するとwhile文を抜けませんが、
もう一度^Z+Enterキーを入力すると抜けるようにはなります。
feof()を使っているので『フラッシュ』のwhile文でループしません。
fgetsで標準入力から改行なしで入力の終わりと判定するのは難しそうです。
ファイルやリダイレクション入力なら正しく終わりを判定してくれますが、
標準入力(=キーボード)からは難しいので最終的に何を行いたいのかを補足して下さい。
もしかしたら別の解決策が見つかるかもしれません。
この回答への補足
最終的には、読み込んだ文字列を元に、禁則処理を適用して原稿用紙として換算することが目的です。
読み込む文字列は、基本的にHTMLファイルのソースで、設定次第では一般的なテキスト文章も利用可能な状態です。
前者の場合、入力後にタグを除去する操作を行っております。
現段階では非対応な状況ではありますが、将来的には標準入力(stdin)とファイル入力の両方に対応できればと考えております。
No.1
- 回答日時:
★些細な記述ミスが数箇所発見。
>*2のgetscharについては、その個数を増やしても同様に無視されるようです。
↑
無視されるとはどういう事ですか?
一時停止しないでexecute()関数を抜けるのですか?
・『お礼』『補足』に些細なミスが数箇所あります。
コンパイル時にエラーが出ませんか?
下に私がデバッグしたソースを載せておきます。
サンプル:
#include <stdio.h>
#include <string.h>
#define SIZE 100
char moji[ SIZE ] = { 0 };
char buff[ SIZE ];
// 実行
void execute( void )
{
//EOF(^Z)になるまで、文字列を受け取る
while ( fgets(buff,sizeof(buff),stdin) != NULL ){
if ( sizeof(moji) < (strlen(moji) + strlen(buff)) ) break;
strcat( moji, buff );
}
puts( "フラッシュ" );
while ( getchar() != EOF ){
;
}
puts( "一時停止" );
getchar(); //*2 これを無視して動作
puts( "抜ける" );
}
// メイン関数
void main( void )
{
int mode, r;
for ( ; ; ){
do {
puts( "入力:" );
r = scanf( "%d", &mode ); //*1 1度目は「1」を入力
while ( getchar() != '\n' ){;}
} while ( r == 0 );
puts( "選択枠" );
switch ( mode ){ //その他選択肢あり
case 1:
execute();
break;
}
}
}
※こちらでは一時停止しますけど。
原因:
>*2のgetcharを無視して、*1のscanfで入力を受け付けなくなります。
これは些細な記述ミスによると思います。
間違い⇒『while(getchar() != '\n'){ };』
正しい⇒『while(getchar() != '\n'){;}』
※セミコロンをブロック内に記述します。
※while文のブロック後には『;』文字は記述できません。基本でしょ。
最後に:
締め切りが早すぎます。
再回答しようとしたら書き込めなかった。
締め切りについては、申し訳ありませんでした。
サンプルで頂いたソースをC&Pの後、コンパイル、実行しましたが、
やはり*2のgetcharを無視して*1のscanfの場所で入力できなくなります。
「getcharの無視」については、「あるのにも関わらず、ない状況と同じ動作をする」という状況です。
while(~){~};については、do{~}while(~);と勘違いしていたようです。
しかしながら、while(~){~};でもコンパイルエラーは表示されなかったことを併記しておきます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2進数の1の数を数える問題
-
double型が正常に認識されてい...
-
WindowsでEOF
-
Userformの入力順序をタブオー...
-
VisualStudio2019のコードアナ...
-
scanf関数について
-
cout関数を使っているのですが...
-
C言語(構造体)
-
Date関数で書いた日付がおかしい
-
配列変数を用いて平均値を求める
-
入力候補を表示させるには・・・?
-
数字以外が入力されたらエラー...
-
VB.NETで16進数+16進数や16進...
-
プログラミングの問題です 「金...
-
scanf が無視されます
-
"scanf"でエンターで改行させな...
-
cin.get(c)について
-
VB カウントダウンタイマーの作...
-
Eclipseコンソール表示を、リセ...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
*をユーザーが入力した数字の数...
-
プログラミング初心者です。 Py...
-
java初心者です。入力されたの...
-
正負を反転させて出力するプロ...
-
EDITコントロールで入力できる...
-
Excel VBAで、Application.Inpu...
-
4桁の数字以外を入力したらエラ...
-
Eclipseコンソール表示を、リセ...
-
入力値が1以下、かつ数字以外の...
-
コマンドプロンプトからのEOFの...
-
電卓の小数点
-
プログラミングの問題です 「金...
-
scanf が無視されます
-
漢字のソートについて
-
scanfが2回使えない・・・?;
-
C言語について
-
Userformの入力順序をタブオー...
-
WindowsでEOF
-
ワードで文字を入力する時の変...
おすすめ情報