Code:
#include"projekti.h"
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
struct country *add_country(struct country *array, char *name)
{
int i;
for (i = 0; array.name != NULL; i++); //Moving through the array until the first NULL character.
struct country *newcountry = realloc(array, sizeof(struct country) * (i + 2)); //Allocate space for a country
if (newcountry == NULL) { //+ space for final NULL character
return NULL; //allocating failed
}
char *country_name = malloc(strlen(name) + 1);
strcpy(country_name, name); //Copying the name of the country to another string, otherwise the names will overwrite eachother.
newcountry.name = country_name;
newcountry.medals.gold = 0;
newcountry.medals.silver = 0;
newcountry.medals.bronze = 0;
newcountry[i + 1].name = NULL; //Adding last null char to the array, so that the process can be repeated
return newcountry;
}
void update_medals(struct country *p, char *name, int number, int g, int s,
int b)
{
int ret;
int count = 0; // Int to control if there exists a entered country with the same name.
for (int i = 0; i < number; i++) { //Moving through the array of structs, until we find the country with the same name as the input.
ret = strcmp(p.name, name); //strcmp returns 0 if the names are equal
if (ret == 0) {
p.medals.gold += g;
p.medals.silver += s;
p.medals.bronze += b;
count++; //Country found!
}
}
if (count == 0) {
printf
("Nonexisting country, check spelling or register the entered country before adding medals.\n");
}
}
void printtable(struct country *array)
{
printf("\n");
for (int i = 0; array.name != NULL; i++) { //Moving through the array of structs until NULL character.
printf("%s %d %d %d\n", array.name, array.medals.gold, array.medals.silver,
array.medals.bronze);
}
printf
("\nContinue adding countries and medals, or quit the program with the command 'Q'\n");
}
void save_table(struct country *p, char *filename, int number)
{
FILE *file;
file = fopen(filename, "w");
for (int i = 0; i < number; i++) {
fwrite(p.name, sizeof(int), 1, file);
}
fclose(file);
printf("File saved successfully!\n");
}
void load_table(struct country *p, char *filename)
{
FILE *file;
file = fopen(filename, "r");
if (file != NULL) {
while (1) {
if (feof(file)) {
printf("File Loaded Successfully!\n");
break;
} else {
fscanf(file, "%s %d %d %d", p->name, &(p->medals.gold),
&(p->medals.silver), &(p->medals.bronze));
}
}
} else {
printf
("File failed to open due to either wrong name input, or nonexisting file.\n");
return;
}
fclose(file);
}
int main()
{
struct country *array = malloc(sizeof(struct country));
array[0].name = NULL; //Initialize array
char input[80]; //User input line
char name[20]; //String for handling the country/file name inpu
int number = 0; //Keeping track of the number of countries
printf("OLYMPIC MEDALS\n");
printf
("Register a new country with the command prefix 'A'. Example: 'A USA'.\n");
printf
("Add medals to existing countries with the prefix command 'M'. Example: 'M USA 1 1 1'.\n");
printf("Print the current table with the command 'L'\n");
printf
("Save the existing table to a file with the command prefix 'W'. Example 'W filename'\n");
printf
("Load an existing file with the command prefix 'O'. Example 'O filename'.\n");
printf("Quit the program with the command 'Q'.\n");
printf("\n");
while (1) { //Loops forever until "break" command
fgets(input, sizeof(input), stdin); //Gets input from user
if (input[0] == 'A') {
sscanf(input, "%*c %s", name); //Reads input, ignoring the first "command" character
array = add_country(array, name);
if (array == NULL) {
printf("\nCreating country failed.");
} else {
number++; //Increases the number of countries
}
printf
("Register another country, or start adding medals to exicting countries.\n");
} else if (input[0] == 'M') {
if (number == 0) {
printf
("You have yet to register a country! Start by registering at least 1 country!\n");
} else {
int g, s, b; // Gold, Silver and Bronze medal count;
sscanf(input, "%*c %s %d %d %d", name, &g, &s, &b); //Reads input, ignoring the first "command" character
update_medals(array, name, number, g, s, b);
}
} else if (input[0] == 'L') {
if (number == 0) {
printf
("You have yet to register a country! Start by registering at least 1 country!\n");
} else {
printtable(array);
}
} else if (input[0] == 'W') {
if (number == 0) {
printf
("You have yet to register a country! Start by registering at least 1 country!\n");
} else {
sscanf(input, "%*c %s", name); //Reads input, ignoring the first "command" character
save_table(array, name, number);
}
} else if (input[0] == 'O') {
if (number == 0) {
printf
("You have yet to register a country! Start by registering at least 1 country!\n");
} else {
sscanf(input, "%*c %s", name); //Reads input, ignoring the first "command" character
load_table(array, name);
}
} else if (input[0] == 'Q') {
free(array);
printf("Exiting program.\n");
break;
}
}
return 0;
}
I'm getting the following error:
Code:
==15== Memcheck, a memory error detector
==15== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==15== Command: /home/agent/projekti.exe
==15==
==15==
==15== HEAP SUMMARY:
==15== in use at exit: 12 bytes in 2 blocks
==15== total heap usage: 9 allocs, 7 frees, 12,996 bytes allocated
==15==
==15== 12 bytes in 2 blocks are definitely lost in loss record 1 of 1
==15== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15== by 0x108BF0: add_country (projekti.c:16)
==15== by 0x10914D: main (projekti.c:117)
==15==
==15== LEAK SUMMARY:
==15== definitely lost: 12 bytes in 2 blocks
==15== indirectly lost: 0 bytes in 0 blocks
==15== possibly lost: 0 bytes in 0 blocks
==15== still reachable: 0 bytes in 0 blocks
==15== suppressed: 0 bytes in 0 blocks
==15==
==15== For counts of detected and suppressed errors, rerun with: -v
==15== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Any ideas where the problem lies?