ホームページ > バックエンド開発 > C#.Net チュートリアル > C言語を使用して入力バッファをクリアするにはどうすればよいですか?学ぶ価値のある方法はたくさんあります

C言語を使用して入力バッファをクリアするにはどうすればよいですか?学ぶ価値のある方法はたくさんあります

php是最好的语言
リリース: 2018-08-01 11:46:59
オリジナル
3085 人が閲覧しました

C 言語には、いくつかの基本的な入力関数があります。

<span style="color:#008000;">//获取字符系列</span><br>
ログイン後にコピー
int fgetc(FILE *stream);
ログイン後にコピー
int getc(FILE *stream);
ログイン後にコピー
int getchar(void);
ログイン後にコピー
//获取行系列
ログイン後にコピー
char *fgets(char * restrict s, int n, FILE * restrict stream);
ログイン後にコピー
char *gets(char *s);//可能导致溢出,用fgets代替之。
ログイン後にコピー
//格式化输入系列
ログイン後にコピー
int fscanf(FILE * restrict stream, const char * restrict format, …);
ログイン後にコピー
int scanf(const char * restrict format, …);
ログイン後にコピー

ここでは、標準入力 (stdin) の場合の入力関数の使用についてのみ説明します。上記の入力関数を見ると、

  • は文字列 の最初の 3 つの関数 fgetc、getc、getchar を取得します。 getchar を例にとると、stdin バッファが空の場合、復帰と改行が発生して関数が戻るまで入力を待ちます。標準入力バッファが空でない場合、getchar は直接戻ります。 getchar が戻ると、バッファーから文字を取得し、それを int に変換し、この int 値を返します。

##MINGW 4.4.3 の FILE 構造のソースコード:

int sscanf(const char * restrict str, const char * restrict format, …);
ログイン後にコピー
  _iobuf
ログイン後にコピー
{
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
	char*	_ptr;//指向当前缓冲区读取位置
ログイン後にコピー
	int	_cnt;//缓冲区中剩余数据长度
ログイン後にコピー
	char*	_base;
ログイン後にコピー
	int	_flag;
ログイン後にコピー
	int	_file;
ログイン後にコピー
	int	_charbuf;
ログイン後にコピー
	int	_bufsiz;
ログイン後にコピー
各コンパイラの実装は異なる場合がありますので、ここでは文字列関数を記述します。 _ptr と _cnt にのみ使用されます。


MINGW 4.4.3 での Getchar() 実装:

	char*	_tmpfname;
ログイン後にコピー
} FILE;
ログイン後にコピー
__CRT_INLINE int __cdecl __MINGW_NOTHROW getchar (void)
ログイン後にコピー
{
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  return (--stdin->_cnt >= 0)
ログイン後にコピー
    ?  (int) (unsigned char) *stdin->_ptr++
ログイン後にコピー
stdin は FILE ポインター タイプです。MINGW 4.4.3 では、getc() および getchar () はインライン関数として実装され、fgetc() は関数として実装されます。ちなみに、C99標準にはインライン関数のサポートが追加されています。

  • ライン シリーズ の fget と get を取得します。get はバッファ サイズを決定できないため、オーバーフローが発生することがよくあります。get 関数は、ここでは推奨または説明されていません。 fgets 関数の場合、Enter キーを押すたびに fgets が返されます。 fgets が正常に返されると、入力バッファー内のデータは、改行文字 '\n' とともに最初のパラメーターが指すスペースにコピーされます。入力データがバッファー長を超える場合、fgets は最初の n-1 までのデータをインターセプトし (n は fgets の 2 番目のパラメーターであり、最初のパラメーターが指すスペースの長さです)、その後 '\n ' 最後に。したがって、fgets は安全です。通常、gets(buf); の代わりに fgets(buf, BUF_LEN, stdin); が使用されます。

  • フォーマットされた入力シリーズ では、ファイル ストリームからの入力をフォーマットするときに fscanf を使用するのは困難です。最も一般的に使用されるのは scanf です。書式設定された入力シリーズ関数は、空白文字以外の文字が見つかるまで空白文字 (スペース、タブ、改行文字) を破棄し、空白文字以外の文字を解析しようとします。以降の文字はフォーマットパラメータに従います。この一連の関数は、正常に解析および割り当てられた変数の数を返します。ファイルの終わりまたはエラーが発生した場合は、EOF を返します。

==================区切り線==================

バッファに関して言えば、次のように宣言される 2 つのバッファ設定関数

setbufsetvbuf について言及する必要があります。 setvbuf

のモード パラメータは次のとおりです:

_IOFBF (フル バッファ): バッファが空の場合はデータを読み取り、バッファがフルの場合はデータをストリームに書き込みます。
  • _IOLBF (ライン バッファ): 一度に 1 行のデータをストリームから読み取るか、ストリームにデータを書き込みます。例:
  • stdio
  • ,

    stdout

    _IONBF (バッファなし): ストリームからデータを直接読み取るか、ストリームにデータを直接書き込みます。そしてバッファもありません。例:
  • stderr
  • setbuf
(stream, buf); in:

buf = = NULL: (void)setvbuf(stream, NULL, _IONBF, 0) と同等;
  • buf は長さ
  • BUFSIZ
  • のバッファを指します: ( void)setvbuf(stream, buf, _IOFBF, BUFSIZ);

    注:
  • BUFSIZ
マクロは stdio.h で定義されています。

伝説的な setbuf

古典的な間違い についても触れておきたいと思います。これについては、「C トラップと欠陥」で説明されています。 問題は次のとおりです: C ランタイム ライブラリは、プログラムがオペレーティング システムに制御を戻す前にクリーンアップ作業を実行する必要があります。その一環として出力バッファをリフレッシュしますが、この時点では main 関数の実行が終了しています。関数内では buf 文字配列が解放されているため、出力がおかしくなって文字化けします。

解決策: buf を静的変数またはグローバル変数に設定するか、malloc を呼び出してメモリを動的に適用することができます。

==================区切り線=================

さあいくつかの一般的なバッファ フラッシュ メソッドを見てみましょう:

##fflush(stdin);Formula

    C99 標準ドキュメントより:
  •     : _filbuf (stdin);
    ログイン後にコピー
    }
    ログイン後にコピー
     setbuf(FILE * restrict stream,  * restrict buf);
    ログイン後にコピー
    int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
    ログイン後にコピー

    fflush は入力ストリームの動作をパラメータとして定義していないことがわかります。
  • しかし、MSDN の fflush の定義:
 main()
ログイン後にコピー
{
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
    int c;
ログイン後にコピー

から、fflush (stdin) が VC でまだ有効であることがわかります。各コンパイラは fflush の未定義の動作を異なる方法で実装するため、入力バッファをリフレッシュするために fflush(stdin) を使用することはお勧めできません。

setbuf(stdin, NULL);式

由前面对setbuf函数的介绍,可以得知,setbuf(stdin, NULL);是使stdin输入流由默认缓冲区转为无缓冲区。都没有缓冲区了,当然缓冲区数据残留问题会解决。但这并不是我们想要的。

  • scanf("%*[^\n]");式(《C语言程序设计 现代方法 第二版》中提到)

这里用到了scanf格式化符中的“*”,即赋值屏蔽;“%[^集合]”,匹配不在集合中的任意字符序列。这也带来个问题,缓冲区中的换行符’\n’会留下来,需要额外操作来单独丢弃换行符。

  • 经典式

 c;
ログイン後にコピー
while((c = getchar()) != '\n' && c != EOF);
ログイン後にコピー

由代码知,不停地使用getchar()获取缓冲区中字符,直到获取的字符c是换行符’\n’或者是文件结尾符EOF为止。这个方法可以完美清除输入缓冲区,并且具备可移植性。

相关文章:

禁止页面缓存的方法 多语言下禁止页面缓存

如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )

相关视频:

C 语言教程

以上がC言語を使用して入力バッファをクリアするにはどうすればよいですか?学ぶ価値のある方法はたくさんありますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート