C 言語 -- getchar() 関数の超詳細な分析 (多次元分析、Xiaobai は一目で理解できます!!!)

目次

I.はじめに

2. getchar() 関数とは

3. getchar() 関数の戻り値の型と仕組み 

4.連続した単一の文字列 (コード デモ)

 5. getchar() 関数のその他の使い方、実践演習 (強調)

(1) テーマに沿った理想のコードを書くが、物足りない効果がある 

(2) 理由分析(原理の詳細説明)

(3) 解決策

 (4) もう一度練習する

5.高度な実践演習:パスワードを入力してください(スーパーキー!!!) 

(1) 再ドリル

 (2) 新たな疑問

(3) 解決策 

六、相互励まし


I.はじめに

    この記事を書く前は、これらの基本的な機能について常に半分理解していたので、ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット ホット タイムズまたは入力文字は常にトピックのフォーマット要件を満たしていません. これまでのところ、私は大物によるいくつかの記事を読み、理解しなければならないことを作成しました.

2. getchar() 関数とは

getchar()----単一の文字を読み取る関数

注: この時点で、1 文字が読み取られます。

           複数の文字を読みたい場合は gets() 関数を使用します

3. getchar() 関数の戻り値の型と仕組み 

int getchar (無効)

getchar() 関数の戻り値の型は int で、整数パラメーターは void です

 このとき、getchar() 関数は 1 文字の入力ではないのに、なぜ戻り値の型が int なのかと誰もが思うでしょう。

1. getchar が実際に返すのは、文字の ASCII コード値 (整数) です。
2. getchar が終了または読み取りに失敗すると、EOF が返されます。

注: EOF はファイルの終わりを意味し、基本的に -1 です。

4.連続した単一の文字列 (コード デモ)

#include <stdio.h>
#include <string.h>
int main()
{
	int ch = 0;  //因为 getchar() 返回类型为 int
	while ((ch = getchar()) != EOF) // 连续输入单个字符
	{
		printf("%c",ch);  // 输出一个字符
		//putchar(ch);    // 此时 printf("%c",ch) 与  putchar(ch)  输出结果一样
  	}

	return 0;
}

 分析: getchar は最初に文字を読み取り、それを ch に入れます。文字が EOF と等しくない場合、ループに入り、文字を出力します。getchar がファイルの最後または最後まで読み取ると、ループを終了する EOF を返します。

注: printf("%c",ch) は putchar(ch) と同じ出力です

※連続入力入力を終了したい場合:ctrl+z

 

 5. getchar() 関数のその他の使い方、実践演習 (強調)

 この時点で、古典的な Niuke の例の質問を見て、通常の質問を行うときに getchar() 関数を正しく使用する方法を確認しましょう。

トピックリンク:文字かどうか判断_にうけトピック_にうけ.com 

タイトル説明: KiKi は入力された文字が文字かどうかを判断したいので、プログラミングを手伝ってください。入力が文字で、出力 (アルファベット) が文字ではない (アルファベットではない) かどうかを判断するプログラムを彼が書くのを手伝ってください。

(1) テーマに沿った理想のコードを書くが、物足りない効果がある 

#include<stdio.h>
int main()
{
    char a;
    while ((a = getchar()) != EOF)
    {
        if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
            printf("%c is an alphabet.\n", a);
        else
            printf("%c is not an alphabet.\n", a);
    }
    return 0;
}

私たちの予想では、文字を出力するとアルファベットが出力され、文字でない場合はアルファベットではないと出力されます. 実行結果を見てみましょう.

 この時点で、誰もがそれが私たちが期待したものと同じではないことに気付くでしょう.出力が出力されるたびに、アルファベットではないものが常にもう1つあります.これにより、コードを送信するときにフォーマットエラーが発生します. これはなぜですか?(とても頭が痛い)

             現時点では、初心者の小さな友達はコンピューターを壊したいですか (その時、私はシャットダウンして去りました、笑) 

(2) 理由分析(原理の詳細説明)

入力機能の原理:

scanf() 関数と getchar() 関数は入力関数に含まれています。これらはすべてキーボードからデータを読み取りますが、キーボードからデータを直接読み取るわけではありません。それらとキーボードの間には、バッファーと呼ばれる領域があります。入力関数は、まずバッファにデータがあるかどうかを確認します. ある場合は、キーボードから入力せずに直接データを取り出します. バッファに何もない場合は、キーボードから入力してから取り出す必要があります. .

図:

 この原則を理解したら、前のコードに戻ってコード図をもう一度分析しましょう。

a = getchar()

コード: getchar() このとき、最初に文字を入力します。たとえば、A !を入力します。

分析:プログラムの実行が開始された後、バッファには何もありません。キーボードからA を入力することしかできません。文字A をバッファに入力するには、実際には無意識のうちに  \nを入力します  。最終的にバッファに表示されるのは  Aです。 \ いいえ

図:

この時点で、バッファは A を置きます\n

注: getchar() 関数は一度に 1 文字しか使用できません 

while ((a = getchar()) != EOF)

この時点では連続入力であるため、最初の getchar() はキーボードの入力を介してバッファーから A を取得し、2 番目の getcgar() はバッファーに \n があることを検出しますが、これはたまたま必要ありません。キーボードから入力できるようにし、\ n を取り除きます。

 今回、分析した結果、出力が アルファベットではないことが問題であることがわかりました.\n が原因です.

(3) 解決策

この時点で、私たちの方向性は非常に明確です。文字を入力するたびにバッファを空にするだけで済みます。

この時点で、getchar の別の使用法を使用して、バッファ内の \n をクリアします。

コードでは、各 while() ループの先頭に getchar() 関数を追加して、各 \n をクリアする必要があります。

#include<stdio.h>
int main()
{
    char a;
    while ((a = getchar()) != EOF)
    {
        getchar();
        if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
            printf("%c is an alphabet.\n", a);
        else
            printf("%c is not an alphabet.\n", a);
    }
    return 0;
}

 この時点でコードを実行し、最終的に成功したことを確認します。

 (4) もう一度練習する

以上の説明が理解できれば、ACに1人で行くことができ、同じタイプの問題がもう1つある場合は、自分で試して、問題を磨くスリルを感じることができます。

トピックリンク:母音か子音かの判定 

5.高度な実践演習:パスワードを入力してください(スーパーキー!!!) 

トピック: 文字列を入力して正しいパスワードかどうかを判定し、正しい場合は Y、そうでない場合は N を入力して続行します

文字が Y と判定された場合は「確認成功」を出力し、それ以外の場合は「確認失敗」を出力します。

(1) 再ドリル

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

 この時点で、Y または N を入力していないことがわかり、確認に失敗して飛び出します。

 この時点で、これを見たときに、このコードの問題に気付いたかもしれません。これは、前の質問と似ています (誰もが「これだ??」と思いますが、心配しないでください。後でまだ問題があります!!! )。同様に、私はまだグラフィカルに分析しています。

scanf("%s", password);

 キーボードからパスワードを入力し、123456 と入力します。123456 を入れるためにキャリッジ リターンも押すので、バッファは123456 になります\n

次に、バッファ内の文字列を読み取る scanf です. scanf の読み取り方法は、 \n の前の内容を読み取るため、123456 を読み取ります.

注: scanf() は、\n の前にコンテンツを読み取ります

printf("请确认密码(Y/N):>");
	int ch = getchar();

 getchar は、バッファにデータ (\n) があることを認識し、キーボードから入力せずに直接取得します。当然、上記の実行結果のシーンが表示されます。N または Y を入力する前に、「確認に失敗しました」がすぐに表示されます。

同様に、scanf() 入力の後に getchar() を追加してクリアします\n 

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	getchar();//把缓冲区中的\n清理掉
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}
	return 0;
}

 この時点で、期待した効果を達成したことがわかります。

 (2) 新たな疑問

今回は本当に期待どおりの効果が得られたのでしょうか? もちろん、そうではありませんでした. そうでなければ、私はずっと前にそれを終えていただろうし、私はまだ疲れ果てています. 新しい質問を見てみましょう.

パスワードを 123456 789 (途中にスペースを入れて) と入力すると、N または Y を入力する前に、すぐに「確認に失敗しました」というポップアップが表示されました。
何が起きてる?一緒に見てみましょう

まず、バッファには何もありません。キーボードからパスワード 123456 789 を入力する必要があります。

 注: その後、scanf はバッファ内のデータをフェッチし、スペースを読み取ると読み取りを停止します (これは scanf の機能です)。したがって、scanf は 123456 だけを取り去り、バッファには(スペース) 789\n が残っています。

 さらに下へ

getchar();

ただし、ここには getchar が 1 つしかなく、1 文字しか読み取れません。つまり、スペースのみが読み取られバッファーには 789\n が残っています。

 さらに下へ

int ch = getchar();

getchar() はバッファ内の7 を受け取るとすぐに受け取るので、キーボードから N や Y を入力する必要はありません。実行すると「確認エラー」から自動で飛び出します。

(3) 解決策 

最初にバッファ内のすべてをクリアする必要があります。
次に、ループを使用します。\n が読み取られない限り、常に getchar を使用して読み取ります。

//把缓冲区中的内容全读走
	while ( getchar() != '\n')
	{
		;
	}

完全なコードを参照してください。

#include<stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	//把缓冲区中的内容全读走
	while (getchar() != '\n')
	{
		;
	}
	puts(password);  // 验证输入的字符串
	printf("请确认密码(Y/N):>");
	int ch = getchar();
	if (ch == 'Y')
	{
		printf("确认成功\n");
	}
	else
	{
		printf("确认失败\n");
	}

	return 0;
}

 

テスト成功!! ! !

六、相互励まし

以下は getchar() 関数の私の理解です. 理解していないか問題を見つけた友人がいる場合は, コメント欄で教えてください. 同時に, 私は他の関数の私の理解を更新し続けます.これからも気をつけてね!! ! ! ! ! ! !  

 

 

おすすめ

転載: blog.csdn.net/weixin_45031801/article/details/127252092