Как можно решить проблему с бесконечным циклом в коде на языке Си?

Как правильно сформулировать вопрос о том, почему при вводе цифр не начинается бесконечный цикл ввода слова $CMD, а как только вводится буква, цикл начинается? Я пишу программу, подобную командной строке, и вот мой код для ознакомления: <br/><br/><pre><code class="objectivec">#include &lt;stdio.h&gt;

int main()
{
    int password;
    int sign_password;

    char intype;
    
    int directory = 2;

// 1
    void CreatePassword()
    {
        system("clear");
        printf("\nCreate your password: ");
        scanf("%d", &amp;password);
        
        while (1)
        {
            printf("Password is created.\nRecreate password?\n\n1.Yes\t2.No\t");
            scanf("%d", &amp;intype);

            if (intype == 1)
            {
                CreatePassword();
            }
            if (intype == 2)
            {
                break;
                directory = 2;
            }
            else
            {
                printf("\nUnknown command!\n ");
            }
        }        
    }


    void CommandLine()
    {
        printf("$CMD: ");
        scanf("%d", &amp;intype);
    }


    void Terminal()
    {
        while (1)
        {
            // Directory system
            switch (directory)
            {
                case 1:
                    CreatePassword();
                case 2:
                    CommandLine();
            }
        }
    }

    Terminal();
}</code></pre>
  • 22 октября 2024 г. 14:23
Ответы на вопрос 2
На основе вашего описания и предоставленного кода, давайте разберемся, почему возникает проблема бесконечного цикла при вводе входных данных. Основная проблема заключается в неправильной обработке типов входных данных и, как результат, в неправильном поведении программы.

### Проблемы в коде

1. **Типы ввода**:
   В функции `CommandLine()` вы определяете `intype` как `char`, но используете его для ввода, ожидая целочисленное значение. Буквы (символы) будут интерпретироваться как их ASCII значение, что может приводить к неожиданному поведению. Например, если ввести букву, это может привести к тому, что условие, проверяющее значения `1` и `2`, не будет срабатывать.

2. **Отсутствие `break` в `switch`**:
   После каждого случая в `switch` у вас нет `break`. Это значит, что когда программа попадает в `case 1`, она будет последовательно выполнять все `case`, которые идут после него, включая `case 2`, что приводит к бесконечному поведению.

### Как решить проблему

1. Измените тип `intype` на `int` в функции `CommandLine` и соответствующих местах:
   
   ```c
   int intype;
   ```

2. Добавьте оператор `break` в каждом случае `switch`, чтобы избежать падения через другие случаи:

   ```c
   switch (directory)
   {
       case 1:
           CreatePassword();
           break; // Добавлено
       case 2:
           CommandLine();
           break; // Добавлено
   }
   ```

3. Обработка некорректного ввода:
   Если пользователь вводит недопустимый символ, программа не сможет корректно прочитать значение. Используйте `scanf` с форматом `" %c"` или если ожидается целое, следите за вводом и очищайте стандартный поток.

### Пример исправленного кода

Вот пример кода с корректировками:

```c
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int password;
    int intype; // Изменено с char на int
    int directory = 2;

    void CreatePassword()
    {
        system("clear");
        printf("\nCreate your password: ");
        scanf("%d", &password);
        
        while (1)
        {
            printf("Password is created.\nRecreate password?\n\n1.Yes\t2.No\t");
            scanf("%d", &intype);

            if (intype == 1)
            {
                CreatePassword();
            }
            else if (intype == 2)
            {
                directory = 2; // Эта строчка может не нужна, так как вы уходите из цикла
                break;
            }
            else
            {
                printf("\nUnknown command!\n");
            }
        }        
    }

    void CommandLine()
    {
        printf("$CMD: ");
        scanf("%d", &intype); // Вводим как int
        // Здесь можно добавить обработку, чтобы управлять командной строкой
    }

    void Terminal()
    {
        while (1)
        {
            // Directory system
            switch (directory)
            {
                case 1:
                    CreatePassword();
                    break; // Добавлено
                case 2:
                    CommandLine();
                    break; // Добавлено
            }
        }
    }

    Terminal();
    return 0; // Неплохо завершить main
}
```

### Заключение

Изменения, которые я предложил, помогут избежать бесконечного цикла и корректно обрабатывать ввод. Убедитесь, что ваша программа проверяет ввод пользователя и обрабатывает возможные ошибки. Надеюсь, это поможет вам решить вашу проблему!
Первое. 
Не стоит определять функции внутри main() - определения функций следует вынести выше main().
scanf("%d", &password);
Что будет, если:
- я введу не число?
- я ничего не введу (пустую строку)?
- я введу строку типа "123 123"?
if (intype == 2)
            {
                break;
                directory = 2;
            }

directory никогда не получит значения 2, потому что break - команда немедленного выхода из цикла.

Скорее всего из-за этого и бесконечный цикл.
Похожие вопросы