C: вложенный do, пока l oop не зацикливается правильно - PullRequest
1 голос
/ 20 июня 2020

Этот код должен -

  • Подсчитать количество символов из входной последовательности.
  • Повторять действие, пока пользователь не выйдет из программы.
  • Использовать вложенные do-while l oop для достижения этой цели.

Но внутренний l oop выполняется только один раз.

Почему?

#include <stdio.h>
int main ()
{
    int x;
    char i, ans;
    i = '\0';
    do
    {
        i = '\0';
        x=0;
        printf("\nEnter sequence of character:");
        do
        {
            i = getchar();
            x++;
        }
        while(i!='\n');
        printf("\nNumber of characters entered is: %d", --x);
        printf("\nMore sequences (Y/N) ?");
        ans = getchar();
    }
    while(ans =='Y' || ans == 'y');

Ответы [ 3 ]

2 голосов
/ 20 июня 2020

Прочитав ответ да / нет (строка с ans = getchar();), вы прочитаете "y" и "\n". Вы потребляете "y" и обрабатываете его, но следующая итерация, когда вы читаете i = getchar();, i, потребляет оставшиеся "\n", поэтому сломает это do-while l oop.

Хотя это не мое любимое решение, простой обходной путь таков:

#include <stdio.h>
int main ()
{
    int x;
    char i, ans;
    i = '\0';
    do
    {
        i = '\0';
        x=0;
        printf("\nEnter sequence of character:");
        do
        {
            i = getchar();
            x++;
        }
        while(i!='\n');
        printf("\nNumber of characters entered is: %d", --x);
        printf("\nMore sequences (Y/N) ?");
        ans = getchar();

        getchar();
    }
    while(ans =='Y' || ans == 'y');
}

Так что просто используйте эти дополнительные "\n". Это будет работать, только если вы наберете "y", а затем "\n" в терминале. Если вы введете какие-либо дополнительные символы, у вас будет неопределенное поведение.

Примечание. В вашей версии попробуйте ввести: "y1234", затем введите при появлении запроса, если вы хотите ввести снова. Вы увидите, что на самом деле вложенный do-while l oop работает и будет считать 4 символа после "y".

1 голос
/ 20 июня 2020

Что произошло:

  • getchar - это макрос, который получает символ из stdin.
  • Разделитель ('\n' в этом case) считается отдельным символом, который остается в буфере и извлекается при следующем вызове getchar().
  • Это приводит к завершению внутреннего l oop.

Что можно сделать:

  • Вставьте следующее после ans = getchar();
    i = getchar();
    if(i != '\n')
        ungetc(i,stdin);

Пояснение нового кода:

  • ungetc(int x,FILE *stream) возвращает символ во входной поток.
  • stdin - стандартный входной поток, определенный в <stdio.h>.
  • Мы читаем символ и кладу обратно, если не '\n'.
1 голос
/ 20 июня 2020

Не совсем уверен, но я думаю, что когда пользователь нажимает ввод до конца sh 1-й символ ввода, который сохраняется в буфере ввода, затем вводится кнопка как символ \n. Попробуйте добавить if(i == '\n') getChar(); после x++;.

...