0

私の仕事は:

入力を # まで読み取り、シーケンス ei が発生した回数を報告するプログラムを作成します。

私はほとんどの場合に機能するものを書きましたが、機能しない場合の入力があります...

この入力のように:(1を返すと仮定)

sdlksldksdlskd
sdlsklsdks
sldklsdkeisldksdlk
#
number of combination is: 0

これはコードです:

int main(void)

{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    char userInput;
    char wordChar[index];

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#')
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[--index] == 'e')
            {
                combinationTimes++;
                ++index;
            }
        }
    }

    printf("number of combination is: %d", combinationTimes);

    return 0;
}

この入力を使用して 1 が得られない理由を教えてください。

本の中で、彼は「あなたの栄英賞を受け取る」でテストするように言ったが、うまくいった...しかし、少し遊んだ後、いつもそうではないことがわかった.

4

2 に答える 2

3

ファイルを配列に読み込む必要はないようです。EOF を読んだり、 EOF に到達したりeiする前に、見つかった回数を追跡する必要があります。#

#include <stdio.h>

int main(void)
{
    int c;
    int ei_count = 0;
    while ((c = getchar()) != EOF && c != '#')
    {
        if (c == 'e')
        {
            int c1 = getchar();
            if (c1 == 'i')
                ei_count++;
            else if (c1 != EOF)
                ungetc(c1, stdin);
        }
    }
    printf("ei appeared %d times\n", ei_count);
    return(0);
}

テスト (プログラムが呼び出さeiれ、からビルドされei.cます):

$ ei < ei.c
ei appeared 0 times
$ sed 1d ei.c | ei
ei appeared 1 times
$ sed 's/#/@/' ei.c | ei
ei appeared 4 times
$

最初のものは#include行で停止し、2 番目#は比較内で停止し、3 番目はファイル全体を読み取ります。また、サンプル データの正しい出力も得られます。


コードの分析

あなたの主な問題は、配列にスペースを割り当てていないことです。配列の次元をindex、たとえば 4096 に変更します。これは、テスト目的には十分な大きさです (実際には、プログラムは配列に注意を払い、オーバーフローしないようにする必要があります — しかし、配列は必要ないと思います)。まったく; 上記のコードを参照してください)。

次の主要な問題は、その名前にもかかわらず、がではなくをgetchar()返すことです。任意の有効な文字と個別の値 EOF を返すことができます。したがって、 a より大きい値を返す必要があります。( を使用すると、次の 2 つのうちのいずれかが発生します。が符号付き型の場合、有効な文字 — 多くの場合、ÿ、y ウムラウト、U+00FF、分音符付きのラテン小文字 Y — は、単なる文字であっても EOF として扱われます)が unsigned 型の場合、EOF に一致する入力はありません。どちらも正しい動作ではありません。)intcharcharcharcharchar

これを修正するのは簡単ですが、あなたのコードは EOF を検出しません。常に EOF を処理します。データの形式が正しくない可能性があります。これは、コード内の簡単な修正です。

3 番目の問題は、printf()ステートメントが改行で終わっていないことです。そうすべき。

ここでのテスト条件は奇妙です:

        if (wordChar[--index] == 'e')
        {
            combinationTimes++;
            ++index;
        }

1 つのプレインクリメントと 1 つのポストインクリメントを使用するのは奇妙ですが、それは単なる一貫性の問題です。さらに悪いことに、文字iが入力に現れ、前にe. 次の行を考えてみましょう。1 として@include <stdio.h>開始します。indexそれは であるiため、インデックスをデクリメントしますが、 でwordChar[0]はないためe、再度インクリメントしませんが、ループの最後でインクリメントするので、ループは 1 を再度チェックし、ループをテストしindex続けますi。長い間ではありません。i@e

デクリメントしてからインクリメントする理由はありませんindex。ちょうど使用:

        if (wordChar[index-1] == 'e')
            combinationTimes++;

それらを修正すると、コードが動作します。問題の主な原因は、十分に大きくない (サイズ 0 の) 配列を使用していたことと、読み取っていたデータで準ランダム メモリを上書きしていたことです。

#include <stdio.h>

int main(void)
{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    int userInput;
    char wordChar[4096];

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#' && userInput != EOF)
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }
    printf("total: %d\n", total);

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[index-1] == 'e')
                combinationTimes++;
        }
    }

    printf("number of combination is: %d\n", combinationTimes);

    return 0;
}

ネストされたものを次のように合理的に書くことができることに注意してくださいif

        if (wordChar[index] == 'i' && wordChar[index-1] == 'e')
            combinationTimes++;
于 2013-01-29T05:10:25.483 に答える
0

wordChar配列値を変更します。

int main(void)

{
    int index = 0;
    int combinationTimes = 0;
    int total = 0;
    char userInput;
    //char wordChar[index]; // index = 0
    char wordChar[255]; // should change the value of array.

    printf("please enter your input:\n");

    while ((userInput = getchar()) != '#')
    {
        if (userInput == '\n')
            continue;

        wordChar[index] = userInput;
        index++;
        total++;
    }

    for (index = 1; index < total; index++)
    {
        if (wordChar[index] == 'i')
        {
            if (wordChar[--index] == 'e')
            {
                combinationTimes++;
                ++index;
            }
        }
    }

    printf("number of combination is: %d", combinationTimes);

    return 0;
}

または多分あなたは使用しpointerてから使用することができます。mallocrealloc

于 2013-01-29T04:00:29.753 に答える