0

私はCを初めて使用し、関数を使用して文字列を取得して印刷する方法を学習しようとしています。を使用している例はどこにでもありますwhile(ch = getchar(), ch >= 0)が、(main()の代わりに)関数に入れるとすぐに機能しなくなります。今、それは無限ループで立ち往生しています...それはなぜですか?

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

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

4 に答える 4

3

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

  1. 文字列「hello」へのポインタを使用してmain呼び出す関数でprintString
  2. 関数はprintString次の文字を読み込もうとしますgetchar()
  3. 'h'の代わりにその文字を保存します

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

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

そして、あなたは5文字を書きたいと思います:'h'、'e'、'l'、'o'、そして別の'o'。

    こんにちは
    ^chはポインタです
    ch*chは「h」です-chは「h」を指します

その最後の「o」の後に何かありますか?がある!A。'\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'! */
}

または、ループでそれを書くことができます(そして異なる引数でmainから呼び出す)...

void printString(char *ch)
{
    while (*ch != '\0')
    {
        putchar(*ch); /* print letter */
        ch = ch + 1;  /* point to the next letter. */
    }
}
于 2010-09-25T17:09:42.323 に答える
3

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

一歩一歩見ていきましょう。あなたが持っているループは、ファイルの終わりに達するまで、stdin から一度に 1 文字を読み取ります。それがch >= 0テストのチェック対象です: 有効な文字を取得している限り、読み続けてください。文字列の文字を印刷する場合、条件が変わります。現在、有効な文字は NUL ( ) ではないものです'\0'。そこで、ループ条件を次のように変更します。

while (*ch != '\0')

次はループ本体を考えます。putchar(*ch)結構です; それはそのままにしておきます。しかしgetchar()、「次の文字を取得する」と同等のステートメントが何であるかを理解する必要はありません。

それはそうでしょうch++chこれにより、ポインタが文字列内の次の文字に進みます。これをループの最後に置くと、文字を出力し、スペースを 1 つ進めてから、次の文字が非 NUL かどうかを確認します。そうであれば、それを印刷し、進めて、チェックします。

while (*ch != '\0') {
    putchar(*ch);
    ch++;
}
于 2010-09-25T16:57:44.973 に答える
2

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

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. Terminates when the read character is < 0 (this won't work on some platforms. Since the result is stored in a char you can't distinguish between EOF and a valid character. ch should be an int, as getchar() returns an int so you can check for EOF)
于 2010-09-25T16:55:33.640 に答える
0

私はただするprintf("%s",str);puts(str);

于 2010-09-25T16:53:21.150 に答える