Я получаю невероятную ошибку в цикле for на языке C. Цикл for работает в 1,2 и 3, но внезапно останавливается

Я знаю, что это клише, но это действительно так.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int chances = 5;         //You can change your chances in there
char sentence[20];      //You can change your sentence's lenght. BUT İF U CHANGE THAT u have change indicator'S lenght
char indicator[20];     //İndicator
char character;         //Variable for your guess 

int woncheck = 0;

void status();          //function
void check();           //function

void main() {

    printf("Wellcome to my hangman game");
    printf("Player 1 please enter your sentence [Max 20 character] ==> ");  
    gets(sentence);         //Get sentence
    
    while (strlen(sentence)>=20)    //Checking for less than 20 char
    {
        printf("Please enter max 20 character ==> ");
        gets(sentence);
    }

    for (int i = 0; i < strlen(sentence); i++) {  // The indicator takes _ as long as the sentence
        if (sentence[i] != ' ') {
            indicator[i] = '_';
        } else {
            indicator[i] = ' ';
        }
    }

    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");   //Screen was skipped 

    status(); //Shows sentence's lenght before all of all

    for (int j = 0; j < chances ; j++) //We gave [changes] rights, so we create loops for a [changes] times
    {
        woncheck = 1;   //We need to check the game

        for (int k = 0; k < strlen(sentence); k++) {
            if (indicator[k] == '_') { // if any indicator letter's is not equal to '_' , it is mean, we not won the game yet
                woncheck = 0;
                break;
            }
        }

        if (woncheck == 1) {
            printf("Player 1 won the game\n");
            break;
        }
    
        printf("Player 2 please enter 1 character ==> ");   //Let's gets letter
        scanf(" %c",&character);
        printf("\n");
        chances--;      // -1 Chance
        check();    //Checking
        status();   //Now where we are in status
        
        if (chances == 0) {
            printf("Player 1 lost the game\n");
            break;
        }
    }
}

void status() {
    for (int  i = 0; i < strlen(sentence); i++)     //As long as the sentence...
    {
/*         if (sentence[i]==' ')       //İf yours sentences have space, we give space
           {
           printf(" ");
           }
*/        printf("%c ",indicator[i]);     //We print the indicator equal to the length of the sentence
    }

    printf("You have %d chances left. \n \n",chances);
}

void check() {
    for (int  i = 0; i < strlen(sentence); i++)
    {
        if (toupper(sentence[i]) == toupper(character))     //if any sentece's letter equal to yours letter indicator gets your letter 
        {
            indicator[i] = character;
        }
        
    }
}

Это обычная игра с палачом.

Но если я попытаюсь ввести 3. букву, программа закроется

Я пробовал этот код в 2 IDE + онлайн-компиляторе, но все время думаю, что получаю логическую ошибку.

Я прошу вас попробовать это на своем компьютере и посмотреть, работает ли оно.

Если он не работает или вы нашли ошибку, буду признателен, если вы добавите ее в комментарий.

Заранее спасибо...

Немедленно прекратите использовать gets(). Это опасная функция, и она была удалена из языка.

Barmar 25.06.2024 01:08
strlen(sentence)>=20 никогда не может быть правдой. sentence — это char[20], поэтому длина может быть не более 19.
Barmar 25.06.2024 01:09

Не используйте глобальные переменные. Если эта переменная нужна другой функции, передайте ее в качестве аргумента.

Some programmer dude 25.06.2024 01:09

Также старайтесь использовать одинаковые отступы и форматирование в целом. Это значительно облегчит чтение и выполнение кода.

Some programmer dude 25.06.2024 01:10

Учитывая char sentence[20], если while (strlen(sentence)>=20) когда-либо истинно, ваш код уже ужасно сломан.

Andrew Henle 25.06.2024 01:10

но если я использую scanf(), я не могу использовать пробел или 2 предложения

Berat Zengin 25.06.2024 01:10

Используйте fgets() вместо gets().

Barmar 25.06.2024 01:11

И у вас получится пять for петель. Кто из них доставляет вам проблемы? Пожалуйста, попробуйте создать минимальный воспроизводимый пример , чтобы показать нам. Также попробуйте использовать отладчик для пошагового выполнения кода, отслеживая переменные и их значения, чтобы увидеть, что происходит на самом деле.

Some programmer dude 25.06.2024 01:11

Моя проблема в том, что когда я пытаюсь угадать букву в третий раз, программа закрывается.

Berat Zengin 25.06.2024 01:14

вы можете попробовать этот код в онлайн-компиляторе

Berat Zengin 25.06.2024 01:14

Среди других предостережений по стилю: void main() { ... } неправильно. Учитывая это, gets и все глобальные переменные, было бы неплохо почитать хорошую современную книгу.

Chris 25.06.2024 01:21

``` for (int j = 0; j < chances ; j++)``` там, если я изменю ``` шансов ```, частичные циклы сработают хорошо.

Berat Zengin 25.06.2024 01:22

@Крис, мне всегда нужно использовать int main?.

Berat Zengin 25.06.2024 01:24

Избегайте использования магических чисел, таких как 20, которые вам придется повторять на протяжении всего кода. Это чревато ошибками, особенно если вы решите изменить ограничение длины строки. Вместо этого используйте именованную константу. Обратите внимание, что ограничение на количество символов составляет не 20, а 19, поскольку вам нужен один байт памяти для нулевого признака конца строки.

paddy 25.06.2024 01:25

@BeratZengin int main() { ... } или int main(void) { ... }, если вам не нужен доступ к аргументам командной строки. Последний из этих двух, если вы хотите иметь возможность без проблем компилировать -Wpedantic или его эквивалент.

Chris 25.06.2024 01:27

Помимо проблем, на которые указывают другие, ваш цикл догадок for (int j = 0; j < chances ; j++) срабатывает раньше, потому что вы уменьшаете chances И увеличиваете j.

Paul Lynch 25.06.2024 01:33

@Chris, я не жду возврата в main, поэтому я не хотел использовать ´´´ int main ´´´, также спасибо, мистер Крис.

Berat Zengin 25.06.2024 01:35

@PaulLynch LOL, вы правы, мистер Пол. Как я этого не увидел?

Berat Zengin 25.06.2024 01:38

@Berat Попробуйте while (chances) вместо цикла for (int j = 0; j < chances ; j++).

Paul Lynch 25.06.2024 01:38

Я обнаружил, что проблема была между «5» и «шансами», но я не до конца ее понимал. я благодарен за твой ответ

Berat Zengin 25.06.2024 01:47
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
20
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Игнорируя другие проблемы с вашим кодом и обращаясь только к заявленной проблеме преждевременного завершения игрового цикла, я вижу, что вы подсчитываете «шансы» двумя противоречивыми способами.

for (int j = 0; j < chances ; j++)
{
    // (omitted)

    chances--;      // -1 Chance
    check();    //Checking
    status();   //Now where we are in status
    
    if (chances == 0) {
        printf("Player 1 lost the game\n");
        break;
    }
}

Вы начинаете с переменной chances, которая инициализируется значением 5, и создаете цикл for, используя j для повторения chances раз.

Однако в этом цикле вы также уменьшаете chances на 1 каждый раз, прежде чем продолжить цикл. Это означает, что ваши переменные состояния при тестировании

  • после первой итерации chances равно 4
  • после второй итерации chances равно 3
  • после третьей итерации chances равно 2, и теперь это условие продолжения не выполняется.

Вам следует выбрать только один подход. Либо отслеживайте ход игры только с помощью j и не изменяйте chances, либо используйте только chances следующим образом:

while (chances > 0)
{
    // (omitted)

    chances--;      // -1 Chance
    check();    //Checking
    status();   //Now where we are in status
}

if (woncheck) {
    printf("Player 1 won the game\n");
} else {
    printf("Player 1 lost the game\n");
}

Вы правы, мистер @paddy, я видел это 2 минуты назад, спасибо за ответ, ценю это

Berat Zengin 25.06.2024 01:43

Несмотря на то, что вам ответили, и ответ выбран. Я не могу удержаться от ответа на комментарий, который вы вставили в свой код:

int chances = 5;         //You can change your chances in there
char sentence[20];      //You can change your sentence's lenght. BUT İF U CHANGE THAT u have change indicator'S lenght
char indicator[20];     //İndicator
char character;         //Variable for your guess 

ты говоришь

НО ЕСЛИ ВЫ ЭТО ИЗМЕНИТЕ, вам придется изменить и длину индикатора. (извините за разное написание)

Для этого вам не нужно добавлять комментарий как таковой.... просто

#define MAX_INDICATOR_LENGTH    20  /* you can change it as you wish, no compromises */

int chances = 5;         //You can change your chances in there
char sentence[MAX_INDICATOR_LENGTH];
char indicator[MAX_INDICATOR_LENGTH];     //İndicator
char character;         //Variable for your guess 

:)

Другие вопросы по теме