Как я могу исправить ошибку If и структуры в C? - PullRequest
0 голосов
/ 27 мая 2020

Моя программа должна запрашивать у пользователя дату последнего полнолуния, проверять правильность данных, а затем спрашивать пользователя, хочет ли он видеть даты следующего или предыдущего полнолуния и сколько. У меня проблемы с «если» и «иначе, если». Я не знаю почему, но программа в основном действует так, будто не видит, что пользователь что-то дал в этой строке scanf_s("%s", &czy_kolejne);, и сразу переходит к else{printf("\nBłędny znak."); }. Я также не уверен, что структура для даты - лучший способ сделать это, потому что у нее есть проблемы с предыдущими датами. Может кто-нибудь дать мне совет?

#include<time.h>
#include<stdlib.h>

int main()
{
    int rok, miesiac, dzien;
    char czy_kolejne;
    int kolejne_pelnie;
    int poprzednie_pelnie;
    printf_s("Kiedy byla ostatnia pelnia ? (DD.MM.YYYY): ");
    scanf_s("%d.%d.%d", &dzien, &miesiac, &rok);

    if (rok >= 0)
    {
        if (miesiac >= 1 && miesiac <= 12)
        {
            if ((dzien >= 1 && dzien <= 31) && (miesiac == 1 || miesiac == 3 || miesiac == 5 || miesiac == 7 || miesiac == 8))
            {
                printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
            }
            else if ((dzien >= 1 && dzien <= 31) && (miesiac == 10 || miesiac == 12))
            {
                printf_s("Poprawna data. %d.%d.%d", dzien, miesiac, rok);
            }
            else if ((dzien >= 1 && dzien <= 30) && (miesiac == 4 || miesiac == 6 || miesiac == 9))
            {
                printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
            }
            else if ((dzien >= 1 && dzien <= 30) && miesiac == 11)
            {
                printf_s("Poprawna data. %d.%d.%d", dzien, miesiac, rok);
            }
            else if ((dzien >= 1 && dzien <= 28) && miesiac == 2)
            {
                printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
            }
            else if (dzien == 29 && miesiac == 2 && (rok % 400 == 0 || (rok % 4 == 0 && rok % 100 != 0)))
            {
                printf_s("Poprawna data. %d.%02d.%d", dzien, miesiac, rok);
            }
            else
            {
                printf_s("Liczba dni w miesiacu jest bledna.");
            }
        }

        else
        {
            printf_s("Nie ma tylu miesiecy.");
        }
    }

    struct tm  t = { 0 };
    t.tm_mday = dzien;
    t.tm_mon = miesiac - 1;
    t.tm_year = rok - 1900;
    int skip = 29;
    t.tm_mday += skip;
    mktime(&t);
    char buffer[30];

    printf("\nCzy wyliczyc daty kolejnych pelni ? (T/N)");
    scanf_s("%s", &czy_kolejne); //The problem starts right here.//

    if ((czy_kolejne=='t') || (czy_kolejne=='T'))
    {

        printf_s("\nIle dat w przod?");
        scanf_s("%d", &kolejne_pelnie);
        for (int i = 1; i <= kolejne_pelnie; i++)
        {
            int skip = 29 * i;
            t.tm_mday += skip;
            strftime(buffer, 30, "\n%d-%m-%Y", &t);
            puts(buffer);
        }
    }
    else if ((czy_kolejne=='n') || (czy_kolejne=='N'))
    {

        printf_s("\nIle dat w tył wyliczyc?");
        scanf_s("%d", &poprzednie_pelnie);
        for (int i= 1; i <= poprzednie_pelnie; i++)
        {
            int skip = 29 * i;
            t.tm_mday -= skip;
            strftime(buffer, 30, "\n%d.%m.%Y", &t);
            puts(buffer);
        }
    }
    else
    {
        printf("\nBłędny znak.");
    }


    return 0;
}

1 Ответ

1 голос
/ 27 мая 2020

По крайней мере две вещи неверны с scanf_s("%s", &czy_kolejne), когда czy_kolejne имеет тип данных char:

Во-первых, %s будет читать строку с завершением 0, но вы предоставляете буфер типа char; это неопределенное поведение, скорее всего, оно просто повреждает память и приводит к странным результатам. Для чтения ровно одного символа используйте формат "%c".

Во-вторых, если вы сделаете czy_kolejne в массиве символов, например char czy_kolejne[10], тогда scanf_s с форматом %s в порядке, но он требует дополнительного аргумента, указывающего размер буфера. Т.е. нужно было бы написать scanf_s("%s", &czy_kolejne, sizeof(czy_kolejne)).

...