Проблема с сохранением структуры в текстовый файл и загрузкой его обратно на стандартный вывод - PullRequest
0 голосов
/ 17 апреля 2019

Эй, у меня есть проблема с моим проектом кода, где я пытаюсь создать проект, который выдерживает олимпийские медали.У меня проблема с созданием текстового файла, который содержит структуру и назван пользователем.У меня также есть проблема, чтобы загрузить структуру.

ПРОБЛЕМА. У меня проблема с созданием текстового файла с именем пользователя, содержащего структуру, и последующей загрузкой его обратно в стандартный вывод.Я не знаю, как исправить мои функции, чтобы сделать это правильно.Теперь моя функция save_file не может даже создать файл.

Пример, если ввод:

A Канада

A США

M США 2 1 1

M Канада 0 0 1

M США 1 3 1

M США -1 0 0

L

W медалей

Q

Я определил свою структуру следующим образом:

typedef struct Olympia
    {
        char* country;
        int gold;
        int silver;
        int bronze;
    }Olympia;

Затем у меня есть функция, которая добавляет страну

int add_country(struct Olympia* data, char* str, int i)
{
    if (str[0] == '\0') //checking that input is correct
    {
        printf("Error! Try again!\n");
    }

    else
    {
        data[i].country = malloc(strlen(str) + 2);  //allocating memory for country name
        strcpy(data[i].country, str);   //adding country to database
        data[i].gold = 0;   //setting medals to zero
        data[i].silver = 0;
        data[i].bronze = 0;
        i++;
    }
    return i;
}

Далее я добавляю медали в каждую страну

int update_medals(struct Olympia* data, char* str, int add_gold, int add_silver, int add_bronze, int i)
{
    int a = 0;
    int b = 0;

    if (str[0] == '\0') //checking that input is correct
    {
        printf("Error! Try again!");
    }

    else
    {
        while (a < i)
        {
            if (strcmp(data[a].country, str) == 0)  //adding medals to right country
            {
                data[a].gold = data[a].gold + add_gold;
                data[a].silver = data[a].silver + add_silver;
                data[a].bronze = data[a].bronze + add_bronze;
                b++;
            }
            a++;
        }

        if (b == 0) //and if the country didn't participate to the olympics
        {
            printf("This country isn't in the Olympics! Try Again!\n");
        }
    }
}

Далее идет функция печати

int print_data(struct Olympia* data, int i)
{
    for (int a = 0; a < i; a++)
    {
        printf("%s %d %d %d\n", data[a].country, data[a].gold, data[a].silver, data[a].bronze);
    }
}

А затем есть две функции, которые не работают.Что мне делать?

Olympia *save_file(Olympia* data, const char* filename, int i)
{
    if (strlen(filename) > 100)
    {
        printf("Filename is too long: Maxium lenght for filename is 100 characters");
        return data;
    }

    char name[100];
    int ret = sscanf(filename, "W %s", name);
    if (ret != 1)
    {
        printf("Error! Try again!");
        return data;
    }


    FILE* file = fopen(name, "w");
    if (!file)
    {
        printf("Error saving file! Try again");
        return data;
    }

    int a = 0;
    while (data[a].country[0] != 0)
    {
        fprintf(file, "%s %d %d %d\n", data[a].country, data[a].gold, data[a].silver, data[a].bronze);
        a++;
    }

    fclose(file);
    return 0;
}

int load_file(struct Olympia* data, char* filename, int i)
{
    int a = 0;

    FILE* file = fopen(filename, "r");
    if (!file)
    {
        printf("Error opening file! Try again");
    }

    struct Olympia* arr = malloc(sizeof(Olympia));

    while (fscanf(file, "%s %d %d %d", data[a].country, data[a].gold, data[a].silver, data[a].bronze))
    {
        i++;
        a++;
        arr = realloc(arr, sizeof(Olympia) * (i + 2));
    }
    arr[a].country[0] = 0;
    fclose(file);
    return arr;
}

и основная функция

int main(void)
{
    char command;
    int gold = 0;
    int silver = 0;
    int bronze = 0;
    int i = 0;

    char* line = (char*)malloc((100) * sizeof(char)); //allocating memory for one stdin line
    char* countryname = (char*)malloc(20 * sizeof(char)); // allocating memory for country name
    char* filename = (char*)malloc(100 * sizeof(char));
    struct Olympia* countrydata = malloc(sizeof(struct Olympia) * 1); //allocating memory for structure

    line = fgets(line, 100, stdin);

    while(1)
    {
        sscanf(line, "%c %s %d %d %d", &command, countryname, &gold, &silver, &bronze);

        switch (command)
        {
            case 'A':

                i = add_country(countrydata, countryname, i);
                countrydata = realloc(countrydata, sizeof(struct Olympia) * (i + 1));
                break;

            case 'M':

                update_medals(countrydata, countryname, gold, silver, bronze, i);
                break;

            case 'L':

                print_data(countrydata, i);
                break;

            case 'W':

                save_file(countrydata, filename, i);
                break;

            case 'O':

                i = load_file(countrydata,filename, i);
                break;

            case 'Q':

                free(line);
                free(countryname);
                free(countrydata);
                return(EXIT_SUCCESS);
        }

        line = fgets(line, 100, stdin);

        if (line == NULL)
        {
            free(line);
            free(countryname);
            free(countrydata);
            return(EXIT_SUCCESS);
        }
    }
}

1 Ответ

0 голосов
/ 18 апреля 2019

Вы звоните save_file(countrydata, filename, i);, не установив filename.Измените на save_file(countrydata, line, i);, так как по какой-либо причине вы ожидаете, что символ команды W будет предшествовать имени.

Тогда в save_file() условие в while (data[a].country[0] != 0) неприменимо, поскольку элемент данных после последнегоне инициализируется.Вместо этого используйте while (a < i).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...