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