Манипулирование файлами через C, чтобы создать топ-5 лидеров - PullRequest
0 голосов
/ 21 сентября 2019

Я создаю игру connect 4 отдельно от проекта и хочу добавить в нее дополнительные функциональные возможности, однако я изо всех сил.

Код - это написанная мной функция, которая требуетstruct (lb лидеров) и пытается прочитать файл для этой сложности всех его входных данных в размере массива lb 6, который включает в себя сложность бота, количество ходов и имя игрока, затем организует его в порядке подсчета ходаи перепечатывает топ 5 обратно в файл.Я установил первый элемент старого массива на данные, передаваемые структурой данных таблицы лидеров для бита функции упорядочения.

Однако, когда я установил его с помощью входов шаблона, каждый из которых был разделен новой строкой, например: 0 7Джеймс 0 13 Джимми 0 8 Джошуа 0 6 Чарли 0 9 Джек

Он печатает это в файл:

0 7 Джеймс 0 13 Джимми 0 8 Джошуа 0 6 Чарли (0 9 Джек 1982289408 0) та же строка

Структура выглядит так же {int turn_count int diff char name [20]}

Я действительно новичок в кодировании, поэтому любая помощь приветствуется!

lb old[6];
lb temp;

FILE *file;



                if (leaderboard.diff == 0){
                file = fopen("leaderboard0.txt", "r+");}
                else if (leaderboard.diff == 1){
                file = fopen("leaderboard1.txt", "r+");}
                else if (leaderboard.diff == 2){
                file = fopen("leaderboard2.txt", "r+");}

                fseek( file, 1, SEEK_SET );
                old[0] = leaderboard;

                for (int i = 1; i < 6; i++){
                fscanf(file, "%i %i %s", old[i].diff, old[i].turn_count, old[i].name);}

                for (int i = 0; i < 6; i++){
                        for (int j = i + 1; j < 6; j++)
                    if (old[i].turn_count >  old[j].turn_count)
                                        {
                                            temp = old[i];
                                            old[i] = old[j];
                                            old[j] = temp;
                                        }}

                for (int i = 0; i < 5; i++){
                fprintf(file, "%i %i %s\n", old[i].diff, old[i].turn_count, old[i].name);
                fclose(file);}

}

1 Ответ

0 голосов
/ 21 сентября 2019

Добро пожаловать в StackOverflow, JJewson

Прежде всего, я настоятельно рекомендую вам правильно сделать отступ для вашего кода.Одна ошибка будет очевидна только в следующем:

lb leaderboard = { ... }; /* was missing from your source code */
lb old[6]; /* you should rename this */
lb temp;

FILE *file;

/* somthing that opens a block was missing from your example source */ {
    if (leaderboard.diff == 0) {
        file = fopen("leaderboard0.txt", "r+");
    } else if (leaderboard.diff == 1) {
        file = fopen("leaderboard1.txt", "r+");
    } else if (leaderboard.diff == 2) {
        file = fopen("leaderboard2.txt", "r+");
    }

    fseek( file, 1, SEEK_SET );
    old[0] = leaderboard;

    for (int i = 1; i < 6; i++) {
        fscanf(file, "%i %i %s", old[i].diff, old[i].turn_count, old[i].name);
    }

    for (int i = 0; i < 6; i++) {
        for (int j = i + 1; j < 6; j++) {
            if (old[i].turn_count >  old[j].turn_count) {
                temp = old[i];
                old[i] = old[j];
                old[j] = temp;
            }
        }
    }

    for (int i = 0; i < 5; i++) {
        fprintf(file, "%i %i %s\n", old[i].diff, old[i].turn_count, old[i].name);
        fclose(file); /* this is the obvious error, it should go below this loop */
    }
    fclose(file); /* here it should be */
}
  • Вероятно, было бы лучше переименовать leaderboard в leader, а после этого переименовать old в leaderboard.
  • Я уже упоминал о необходимости переместить вызов fclose за пределы цикла.Вы закрываете файл после первой записи.
  • Я не понимаю ваше первое использование fseek( file, 1, SEEK_SET );: Почему вы пропускаете первый символ файла?(Смещение файла начинается с 0, а не с 1).Также: после успешного выполнения fopen указатель файла всегда указывает на начало файла.
  • После прочтения таблицы лидеров вы должны fclose файл и открыть его для (пере) записи.,(Лучше сохранить резервную копию, если важна таблица лидеров).Итак: Откройте "r" для чтения, чтения, закрытия, откройте "w" для записи, записи, закрытия.
  • Вы не проверяете ошибки в своем коде.Вы должны исправить это и сообщить пользователю об ошибке и попытаться обработать ошибку как можно более изящно.(То есть не теряйте свою таблицу лидеров, если запись не удалась.)
  • Относительно добавленной части 1982289408 0: убедитесь, что ваш новый лидер (struct `leaderboard´) правильно инициализирован).
  • ВашУ алгоритма есть небольшая проблема: новый игрок, который был точно так же хорош, как и предыдущий, вытеснит предыдущего из списка лидеров.Чтобы это исправить, загрузите файл в old[0..4] и поместите нового лидера в old[5] (вместо того, чтобы поместить его в old[0], а содержимое файла в old[1..5])
  • Незначительное улучшение: Цикл сортировки:для (int i = 0; i <6; i ++) для (int j = i + 1; j <6; j ++) <code>-> the для i loop only needs to run from 0 .. 4, so для (int i = 0; i <5; i ++) `будет достаточно. </li>
...