Создание игры на C, а не на С ++. Нужна помощь с сохранением, заменой и сортировкой баллов в текстовом файле - PullRequest
1 голос
/ 02 мая 2020

Я пытаюсь закодировать функцию в C! Не C ++. Я не мог понять, как на самом деле go об этом, так что это всего лишь набросок того, что я хотел бы сделать. Цель этой функции - сохранить 10 лучших результатов в текстовый файл. Это должно иметь имя победителя и количество побед рядом с их именем. Каждый раз, когда раунд заканчивается, победитель будет печатать свое имя в файле с общим количеством побед. Если победивший пользователь выигрывает, его имя должно появляться только один раз. Ниже приведен пример того, как должен выглядеть txt-файл при отображении и что я пытаюсь go для кода.

EX.

1  Joe 10
2  Jen 8
3  Bob 7
4  Caleb 6
5  Lance 5
6  Siobhan 3
7  Laurel 2
8  Jack 2
9  Gabriel 1
10 Timmy 1

Схема функция

1 Ответ

0 голосов
/ 03 мая 2020

Вам нужна структура данных для представления каждой записи. Самое простое, что приходит на ум, это что-то вроде

struct record_entry{
    char name[BUFLEN];
    int score;
};

Тогда вам нужна другая структура данных для хранения этих entry_record объектов. В идеале, что-то вроде карты C ++ или Java HasMap (то есть таблица ha sh) для хранения всех записей с использованием поля name в качестве ключей. Однако для этого необходимо реализовать собственную таблицу ha sh, а если вы не хотите этого делать, вы можете использовать C массивы.

Использовать функцию qsort стандартной библиотеки для сортировки записей в массиве. Простая функция compar для struct entry_record может быть

int cmp_score(const void* e1, const void* e2){
    int s1, s2;
    s1 = ((struct record_entry*)e1)->score;
    s2 = ((struct record_entry*)e2)->score;
    if (s1 < s2)
        return -1;
    else if (s1 == s2)
        return 0;
    else
        return 1;
}

Затем вам понадобится функция для обновления вашей структуры данных (ха sh таблица или массив) на основе новой записи. Вы должны реализовать что-то похожее на insert_or_assign() метод std :: map (C ++ 17) или put() метод Java класса HashMap . Ниже приведена простая функция, которая достигает этого

size_t update_records(struct record_entry **ep, size_t n, struct record_entry ne){
    size_t i;
    int exist=0;
    size_t nsize = n;
    struct record_entry *tmp = *ep;

    /* check if the entry is already there */
    for (i=0; i<nsize; i++){
        if (strcmp(tmp[i].name, ne.name) == 0){
            exist = 1;
            break;
        }
    }

    if (exist){
    /* update the record */
        tmp[i].score = ne.score;
    } else {
    /* add a new entry */
        nsize++;
        tmp = realloc(*ep, nsize * sizeof(struct record_entry));
        strncpy(tmp[nsize-1].name, ne.name, BUFLEN);
        tmp[nsize-1].score=ne.score;
    }

    /* sort the array */
    qsort(tmp, nsize, sizeof(struct record_entry), cmp_score);

    *ep = tmp;

    return nsize;
}

update_records возвращает размер нового массива; n+1 если запись, которую вы передаете в качестве аргумента, отсутствует в массиве (т. Е. Новая запись), или n, если она уже существует. Конечно, он обновляет существующую запись в последнем случае.

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

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

#define BUFLEN     32
#define N    4

struct record_entry{
    char name[BUFLEN];
    int score;
};

int cmp_score(const void* e1, const void* e2){
    int s1, s2;
    s1 = ((struct record_entry*)e1)->score;
    s2 = ((struct record_entry*)e2)->score;
    if (s1 < s2)
        return -1;
    else if (s1 == s2)
        return 0;
    else
        return 1;
}

size_t update_records(struct record_entry **ep, size_t n, struct record_entry ne){
    size_t i;
    int exist=0;
    size_t nsize = n;
    struct record_entry *tmp = *ep;

    /* check if the entry is already there */
    for (i=0; i<nsize; i++){
        if (strcmp(tmp[i].name, ne.name) == 0){
            exist = 1;
            break;
        }
    }

    if (exist){
    /* update the record */
        tmp[i].score = ne.score;
    } else {
    /* add a new entry */
        nsize++;
        tmp = realloc(*ep, nsize * sizeof(struct record_entry));
        strncpy(tmp[nsize-1].name, ne.name, BUFLEN);
        tmp[nsize-1].score=ne.score;
    }

    /* sort the array */
    qsort(tmp, nsize, sizeof(struct record_entry), cmp_score);

    *ep = tmp;

    return nsize;
}

int main(){
    struct record_entry *entries, *p, new_entry;
    int i;
    size_t ns;

    entries = malloc(N * sizeof(struct record_entry));

    strncpy(entries[0].name, "Test0", BUFLEN);
    entries[0].score=0;
    strncpy(entries[1].name, "Test1", BUFLEN);
    entries[1].score=1;
    strncpy(entries[2].name, "Test2", BUFLEN);
    entries[2].score=2;
    strncpy(entries[3].name, "Test3", BUFLEN);
    entries[3].score=3;

    /* sort the array */
    qsort(entries, N, sizeof(struct record_entry), cmp_score);

    printf("before\n");
    printf("===============\n");
    for (i=N-1; i>=0; i--){
        printf("%d %s\t%d\n",i ,entries[i].name, entries[i].score);
    }

    printf("\nname : ");
    scanf("%s", new_entry.name);
    printf("score : ");
    scanf("%d",&new_entry.score);
    getc(stdin);

    ns = update_records(&entries, N, new_entry);

    printf("\nafter return\n");
    printf("===============\n");
    for (i=ns-1; i>=0; i--){
        printf("%d %s\t%d\n",i ,entries[i].name, entries[i].score);
    }

    free(entries);

    return 0;
}

Когда я запускаю этот код с новой записью

before
===============
3 Test3    3
2 Test2    2
1 Test1    1
0 Test0    0

name : test
score : 7

after return
===============
4 test    7
3 Test3    3
2 Test2    2
1 Test1    1
0 Test0    0

и когда я обновляю существующую запись

before
===============
3 Test3    3
2 Test2    2
1 Test1    1
0 Test0    0

name : Test2
score : 9

after return
===============
3 Test2    9
2 Test3    3
1 Test1    1
0 Test0    0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...