Указатель файла становится NULL на второй итерации цикла while

Я кодирую текстовую игру, в которой вводимые пользователем данные сравниваются со списком команд, доступных в имеющемся у меня текстовом файле.

Он работает нормально, но я хочу, чтобы он выполнялся в цикле, чтобы пользователь мог выполнять несколько действий перед вводом команды, которая прерывает цикл и перемещает программу. К сожалению, мой указатель на файл становится NULL на второй итерации цикла и, таким образом, полностью выходит из программы.

Отступы немного сбивают с толку, за что прошу прощения:

    int mansionOutside(void)
    {
        int stop = 1; //control variable for while, yeah I know its a shit method of doing it, sue me
        char choice[25]; //Variable to store user input
        char word_match[15] = "outside"; //counter and .txt will be strcat to it
        char text_line[73]; //size of line for txt files
        char line1[25]; //takes current line being read from file
        char temp[2]; //character and '\0' so counter can be made into a string and strcat into word_match
        int counter = 1; //counts number of lines
        int stop2 = 1;
        while (stop2 == 1)
        {
            FILE *fptr;
            fptr = fopen("mansion_commands.txt", "r"); //opens file
            int lookdoor_counter = 0;
            printf("%p\n", fptr);
            if (fptr == NULL)
            {
                perror("ERROR!"); //Error handling for not opening file
                exit(EXIT_FAILURE);
            }
            else
            {
                while (stop == 1)
                {   
                    puts(""); //newline, as the previous function ends in a text line
                    fgets(choice, sizeof choice, stdin); //store input in choice with buffer overflow protection

                    while (fgets(line1, 25, fptr) != NULL) //reads until newline
                    {
                        if (strcmp(line1, choice) == 0) //if choice is equal to the current line
                        {
                            //printf("%s\n", line1); //debugging print
                            if (strcmp(line1, "LOOK door") == 0)
                            {
                                lookdoor_counter++; //so that on entering LOOK door a second time, a different
                        //message will appear
                            }
                        stop = 0; // will exit from loop
                        break; //break ensures we can use the current counter value for later
                    }
                    else
                    {
                        counter++;
                        //printf("%s + %s\n", line1, choice); //debugging
                    }
                }

            if  (stop == 1)
            {
                printf("I dont understand\n"); 
                //printf("%d\n", counter);
                //printf("%s\n", line1);
                //printf("%s\n", choice);
                counter = 1; //counter is reset to be able to try again
                rewind(fptr);
            }
        }
        fclose(fptr);
        if (lookdoor_counter == 2)
        {
            counter += 1;
        }
        counter = counter + '0'; //convert counter digit to its equivalent ascii
        temp[0] = counter; 
        temp[1] = '\0'; //temp becomes a string with counter and EOF char
        //printf("%c\n", counter);

        strncat(word_match, temp , 1); //wordmatch gets counter strncat to it
        strcat(word_match, ".txt"); /*If the string is found on the second line
        word_match will be (outside2.txt), which contains the appropriate 
        message for that user command*/
        //printf("%s\n", word_match); //debugging
        if (strcmp(word_match, "outside4.txt") == 0)
        {
            stop2 = 0;
        }
        fptr = fopen(word_match, "r"); //we open word_match file
        if (fptr == NULL)
        {
            printf("ERROR!\n"); //error handling
            exit(EXIT_FAILURE);
        }
        else
        {
            //printf("Debugging : File opened Successfully\n");

            while (fgets (text_line, 72, fptr) != NULL)
            {
                printf("%s", text_line); // Prints every Line with a 2 sec delay
                //delay(2);
            }
        }
    }
    fclose(fptr);
}
return 1;

}

Используйте пошаговый отладчик и проверьте код ошибки

Ôrel 17.12.2018 14:49

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

raphael_mav 17.12.2018 15:03

Что делает rewind(fptr);?

Francesco Boi 17.12.2018 15:10

Оказывается, проблема была довольно простой, на самом деле это было из-за плохого отступа, не дающего понять, когда цикл начался или закончился, я разбиваю все это на более мелкие функции, хотя теперь оно работает так, как задумано.

Lord Darias 17.12.2018 15:51

@AlbertoDarias Итак, это был важный урок.

glglgl 17.12.2018 15:52
Стоит ли изучать 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
5
229
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
fptr = fopen("mansion_commands.txt", "r"); //opens file
if (!fptr)perror("fopen");

добавьте это условие if и найдите в нем фактическую ошибку. Может у вас нет разрешения на fs или путь неверен и т. д.

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