掲示板ランキング  プラスター(肩こり・腰痛・筋肉痛の塗り薬)


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.7243

改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/17 17:25:33)


はじめまして。質問させて頂きます。
環境はWindowsXP、コンパイラはフリーのBorland C++5.5.1です。

題名の通りなのですが、コンソールからfgets()などで
文字列を読み取る場合、標準入力に改行文字が残ってしまい、
その後、意図した動作にならない場合があります。
(scanfなどで入力待ちにならない)
getchar()等を入れて改行文字を食べてもらうとうまくいくのですが、
どうも良い方法ではないような気がしています。
fflush()は出力ストリームにしか使ってはいけないそうですし。。
一般的に、こういった場合、どのような方法を取るべきなのでしょうか。

自分なりに考えたところ、
1行ずつ読み取るのがそもそも間違いなのかと思い、
1文字ずつ配列に格納しようとgetche()を使ってみました。
以下のようなプログラムを作ってみたのですが、
入力する度にコンソール上に、右斜め上に次々に文字が
表示されています。
(うまく表現できませんが、1234の順で入力すると
 ↓こんな感じにコンソールに表示されます。
   4
  3
 2
1



このプログラムのどこに問題があるのかも含め、
ご指摘いただけますでしょうか。
最大文字数入力するか、改行(enter)まで配列に格納している
つもりのプログラムです。(全角文字は考えていません)

#include<conio.h>


#define MAX 10

int main(void)
{
    int ch;
    int i=0;
    char str[MAX];
    
    while(1)
    {
        ch = getche();
        
        if( ch == '\n' )
        {
            str[i] = '\0';
            break;
        }
        if( i == (MAX-1) )
        {
            i++;
            str[i] = '\0';
            break;
        }
        str[i] = ch;
        i++;
    }

    cprintf("%s\n",str);
    
    return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:改行文字を読み飛ばしたい 7245 επιστημη 2007/03/18 03:08:31
<子記事> Re:改行文字を読み飛ばしたい 7251 επιστημη 2007/03/18 12:10:51
<子記事> Re:改行文字を読み飛ばしたい 7266 chu- 2007/03/19 11:39:40


No.7245

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/18 03:08:31)
http://blogs.wankuma.com/episteme/


>題名の通りなのですが、コンソールからfgets()などで
>文字列を読み取る場合、標準入力に改行文字が残ってしまい、
>その後、意図した動作にならない場合があります。

かわりにgetsじゃダメですか?



この投稿にコメントする

削除パスワード

No.7246

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/18 04:53:51)


>かわりにgetsじゃダメですか?

返信ありがとうございます。
あれからfgets()とgets()の違い等調べまして、
なぜこうなるのかちょっとわかってきました。
まだ勉強中ですが。。
gets()だと確かに出来るのですが、ちょっと危険なのと
Warningが出るコンパイラもあるようですので、
もうちょっと勉強してみます。

そちらの方は糸口が掴めたのですが、
自分作成のgetche()のプログラムがなぜ、あのような
動作になってしまうのかがわかりません。
なぜなのでしょうか。。






この投稿にコメントする

削除パスワード

No.7251

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/18 12:10:51)
http://blogs.wankuma.com/episteme/


>題名の通りなのですが、コンソールからfgets()などで
>文字列を読み取る場合、標準入力に改行文字が残ってしまい、
>その後、意図した動作にならない場合があります。

本当?

fgetsは標準入力に改行を残さず、
読み込んだ文字列の末尾にくっついてるはずですけど。

#include <stdio.h>

int main() {
  char input[256];
  int n;
  fgets(input, 256, stdin);
  scanf("%d",&n);
  printf("[%s] %d\n", input, n);
  return 0;
}

実行結果
abc ←入力(最後に改行)
123 ←これも入力
[abc ←出力。inputの末尾に改行があるため ']'が次行へ。
] 123



この投稿にコメントする

削除パスワード

No.7256

Re:改行文字を読み飛ばしたい
投稿者---たかぎ(2007/03/18 15:50:03)
http://takagi.in/


>>題名の通りなのですが、コンソールからfgets()などで
>>文字列を読み取る場合、標準入力に改行文字が残ってしまい、
>>その後、意図した動作にならない場合があります。
>
>本当?

入力した文字数が、fgetsで指定したバッファサイズ以上になると、確かに質問者さんが問題視しているとおりの現象になります。
バッファサイズが足りない場合のことを問題にしているのであれば、getsでは役不足です。ここは、
char s[256];
scanf("%255s%*[\n]%*c", s);
とするのが一番手っ取り早い気がします。



この投稿にコメントする

削除パスワード

No.7257

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/18 17:10:53)


返信ありがとうございます。
曖昧な書き方で申し訳ありませんが、
fgets()の仕様をちゃんと理解できておらず、
このスレッドを立てましたが、
その後色々調べていくうちに自分の勘違いに気付きまして、
7246の「糸口がつかめてきた」状態です。
たかぎさんのご指摘通りの勘違いでした。

まだ勘違いして理解してたら嫌なので念のため確認ですが、
12345をfgets()で標準入力に改行を残さず読み込みたい場合は、
7バイト必要という事で間違いないでしょうか。


この投稿にコメントする

削除パスワード

No.7258

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/18 17:22:06)
http://blogs.wankuma.com/episteme/


>12345をfgets()で標準入力に改行を残さず読み込みたい場合は、
>7バイト必要という事で間違いないでしょうか。

やってみたらわかるやん。



この投稿にコメントする

削除パスワード

No.7259

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/18 17:39:55)


やってみましたし動きました。
理解が間違っていないか聞いているのですが。
>やってみたらわかるやん。




この投稿にコメントする

削除パスワード

No.7260

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/18 17:45:00)
http://blogs.wankuma.com/episteme/


>やってみましたし動きました。
>理解が間違っていないか聞いているのですが。
>>やってみたらわかるやん。

なぜバッファサイズが7となるのか、その根拠を示さんと
その理解が正しいかわからんでしょ。




この投稿にコメントする

削除パスワード

No.7261

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/18 18:11:19)


確かにおっしゃる通りです。
12345(5バイト)+ \n + \0で7バイトですよね。

>なぜバッファサイズが7となるのか、その根拠を示さんと
>その理解が正しいかわからんでしょ。
>




この投稿にコメントする

削除パスワード

No.7263

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/18 21:57:09)
http://blogs.wankuma.com/episteme/


>確かにおっしゃる通りです。
>12345(5バイト)+ \n + \0で7バイトですよね。

ですね。
ただ、ヒトは気まぐれだから "   12345   "って入力するかも知れない。
なんてことを考慮"しない"ならそれで十分かと。




この投稿にコメントする

削除パスワード

No.7264

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/18 23:39:05)


なるほど。
とりあえずfgets()について自分の勘違いと
正しい仕様が理解できたのでよかったです。
ありがとうございました。

getche()の方はなぜああなるか依然わかりません。
どこか詳しく解説しているサイト等ないでしょうか。



この投稿にコメントする

削除パスワード

No.7265

Re:改行文字を読み飛ばしたい
投稿者---επιστημη(2007/03/19 09:44:22)
http://blogs.wankuma.com/episteme/


> 入力する度にコンソール上に、右斜め上に次々に文字が
> 表示されています。

Microsoft Visual C++ 8.0 では再現できませんでした。
なのでわかりません。



この投稿にコメントする

削除パスワード

No.7266

Re:改行文字を読み飛ばしたい
投稿者---chu-(2007/03/19 11:39:40)


環境: Win2000 Borland C++ 5.5.1

まず最初に、conio.h を使ったことがないので詳しくはありません。

>  ↓こんな感じにコンソールに表示されます。
> 
>    4
>   3
>  2
> 1

コピペしてコンパイル→実行してみると、確かに変な動きをすることがありますね。
質問者さんの言うとおり、キーを押すごとに右上にカーソルが移動していくという不思議なモードになることがありました。
しかし、いつもそう動くわけではなく、cls で画面をクリアしてから実行すると再現しなかったりとわけがわかりません。

conio.h を使うことに特に理由がなければ stdio.h 等の標準関数で解決してはどうでしょうか。
環境に依存しない方が、多くアドバイスをもらえると思います。

以前に似た質問をしたことがあるので参考にしてください。

入力バッファに残ったデータを破棄したい
http://f4.aaa.livedoor.jp/~pointc/No.20131.html



この投稿にコメントする

削除パスワード

No.7271

Re:改行文字を読み飛ばしたい
投稿者---HIKARI(2007/03/20 01:49:36)


返信ありがとうございます。
教えていただいた過去ログで勉強します。
VC等の環境では再現しないのですね。
てっきりそういう動きをするプログラムに
なってしまっているのかと思っていました。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ