почему элементы массива хранят значение n-1 вместо n - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь сделать программу, которая хранит длину каждого слова в массив и распечатать его. Но длина n не печатается, вместо этого печатается длина n - 1.

#include <stdio.h>

#define IN 1
#define OUT 0
#define MAXLENGTH 10

int main(void)
{
    int i, c, state, word;
    int array[MAXLENGTH];

    state = OUT;
    word = 0;

    for (i = 0; i < MAXLENGTH; i++)
        array[i] = 0;

    while ((c = getchar()) != EOF)
    {
        if (c == '\n' || c == ' ')
            state = OUT;
        else if (state == IN)
        {
            ++array[word];
        }
        else if (state == OUT)
        {
            state = IN;
            ++word;
        }
    }

    for (i = 1; i < MAXLENGTH; i++)
        if (array[i] != 0)
            printf("cuvantu %d are %d caractere \n", i, array[i]);
}

Ответы [ 3 ]

0 голосов
/ 09 мая 2019

Рассмотрим этот код:

    if (c == '\n' || c == ' ')
        state = OUT;
    else if (state == IN)
    {
        ++array[word];
    }
    else if (state == OUT)
    {
        state = IN;
        ++word;
    }

Когда c является новой строкой или пробелом, оно меняет состояние на OUT, что, вероятно, означает вне слова.

Когда c - другой символ:

  • Если состояние IN, он подсчитывает символ путем увеличения array[word], что отслеживает длину текущего слова.
  • Если состояние OUT, оно меняет состояние на IN и увеличивает word, чтобы начать отсчет нового слова.

В последнем случае текущий символ не учитывается - приращение до array[word] не выполняется. Чтобы исправить это, введите ++array[word]; в последнем случае:

    if (c == '\n' || c == ' ')
        state = OUT;
    else if (state == IN)
    {
        ++array[word];
    }
    else if (state == OUT)
    {
        state = IN;
        ++word;
        ++array[word];
    }
0 голосов
/ 09 мая 2019

Похоже, это хорошее упражнение, позволяющее избежать частых ошибок.

Хотя это может быть решено многими способами, в следующем фрагменте показано, как изменить логику размещенного конечного автомата, чтобы массив длин мог заполняться с самого начала, не пропуская первый элемент array[0], вплоть до (но не более) его максимальный размер.

#include <stdio.h>

#define IN 1
#define OUT 0
#define MAXLENGTH 16

int main(void)
{
    int array[MAXLENGTH] = {0};

    int c, state = OUT,   
        n_words = 0; //  <-- this name may better convey the purpose of this variable

    while ((c = getchar()) != EOF)
    {
        if (c == '\n' || c == ' ')  // <-- Consider isspace() and iscntrl() instead.
        {
            // We are between words.
            state = OUT;
        }
        else
        {
            // Check the current state before updating it.
            if ( state == OUT )
            {
                // A new word starts, but there might not be enough space.
                if ( n_words == MAXLENGTH )
                {
                    // Here, the rest of the stream is not consumed
                    ungetc(c, stdin);
                    break;     
                }
                ++n_words; 
            }
            state = IN;

            // Array indices are zero based, so the current word is:
            ++array[n_words - 1];
        }
    }

    if ( c != EOF )
        fprintf(stderr, "Sorry, out of space.\n");

    // You can use the actual number of read words to limit the extent of the loop
    printf(" %5s  %5s\n---------------\n", "Word", "Length");
    for (int i = 0; i < n_words; i++)
        printf("%5d  %5d\n", i + 1, array[i]);
}

Код для тестирования здесь .

0 голосов
/ 09 мая 2019

Попробуйте изменить второй for цикл как for (i = 0; i < MAXLENGTH; i++)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...