質問

私は C の初心者で、文字列を取得し、関数を使用して出力する方法を学ぼうとしています。を使用した例がどこでも見られます while(ch = getchar(), ch >= 0), 、しかし、(main() の代わりに) 関数に入れるとすぐに機能しなくなります。今まさに無限ループに陥っています…。何故ですか?

// from main():
// printString("hello");

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}
役に立ちましたか?

解決

あなたの説明に基づいて、あなたはただ欲しいだけです:

void printString(char *ch)
{
  while(*ch) {
     putchar(*ch);
     ch++;
  }
}

元の機能:

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}

たくさんのことをします:

  1. Stdinの文字を読み取ります
  2. stdinから読んだキャラクターを保存します。 ch (文字通りの文字列を渡すと、これは機能しないかもしれません。
  3. stdoutに文字を書きます。
  4. 読み取り文字が<0の場合に終了します(これは一部のプラットフォームでは機能しません。結果はeofと有効な文字を区別できないcharに保存されます。chはintである必要があります。 intしたがって、EOFを確認できます)

他のヒント

getchar() stdinからのユーザー入力を読み取ります。渡されている文字列を印刷したい場合は、必要ありません getchar().

段階的に考えましょう。あなたが持っているループは、stdinからファイルの終わりに達するまで、1つの文字を1つの文字を読み取ります。それがそうです ch >= 0 テストチェック:有効な文字を取得している限り、読み続けてください。文字列の文字を印刷するために、条件は変わります。今では有効なキャラクターはnulではないものです('\0')。したがって、ループ条件を次のように変更します。

while (*ch != '\0')

次はループ本体を把握することです。 putchar(*ch) 結構です;そこに残します。しかし、なし getchar() 「次のキャラクターを取得する」と同等のステートメントが何であるかを把握する必要があります。

そうでしょう ch++. 。これはを進めます ch 文字列の次の文字へのポインタ。ループの端に置くと、文字を印刷し、1つのスペースを進めてから、次の文字が非nulのかどうかを確認します。もしそうなら、それを印刷し、前進し、チェックします。

while (*ch != '\0') {
    putchar(*ch);
    ch++;
}

ここで何が起こるかは次のとおりです。

  1. 関数内で main あなたが呼ぶ printString 文字列「hello」へのポインタを使用
  2. printString 関数は次の文字を読み取ろうとします getchar()
  3. そしてその文字を「h」の代わりに保存します

言語のルールでは、その「h」を変更しようとすることは未定義の動作であると規定されています。運が良ければ、プログラムはクラッシュします。非常に運が悪い場合は、プログラムが機能しているように見えます。

要するに: getchar() 読書に使用されます。 putchar() 書き込みに使用されます。

そして、あなたは 5 文字を書きたいとします。「h」、「e」、「l」、「o」、そしてもう 1 つ「o」。

    hello
    ^            ch is a pointer
    ch           *ch is 'h' -- ch points to an 'h'

最後の「o」の後に何かありますか? がある!'\0'. 。ゼロバイトは文字列を終了します。それでこれを試してみてください( printString("hello");) ...

void printString(char *ch)
{
    putchar(*ch); /* print 'h' */
    ch = ch + 1;  /* point to the next letter. */
                  /* Note we're changing the pointer, */
                  /* not what it points to: ch now points to the 'e' */
    putchar(*ch); /* print 'e' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'o' */
    ch = ch + 1;  /* point to the next letter. What next letter? The '\0'! */
}

または、それをループ内に書くこともできます(そして、異なる引数を使用してメインから呼び出す)...

void printString(char *ch)
{
    while (*ch != '\0')
    {
        putchar(*ch); /* print letter */
        ch = ch + 1;  /* point to the next letter. */
    }
}

私はやります printf("%s",str); また puts(str);

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top