Откройте динамический URL с помощью C ++ - PullRequest
2 голосов
/ 08 октября 2019

Получил следующий URL - https://barbaraperes.com/2017/08/31/2017_08_31.csv, 2017 года, 08 месяца и 31 дня.

В настоящее время я создаю сценарий, который работает со всеми днями, месяцами и годами сданный момент в настоящее время. Для каждого дня скрипт изменяет URL (строку), вставляя дни, месяцы и годы, и открывает его .

Это текущий код

#include <time.h>
#include <string>
#include <iostream>

int main() {
    struct tm date;

    date.tm_year = 2007 - 1900; // tm_year (int) years since 1900
    date.tm_mon = 6; // tm_mon (int) months since January (0-11)
    date.tm_mday = 1; // tm_mday (int) day of the month (1-31)

    time_t end_date = time(NULL);

    std::cout << " =========================================================== \n";

    std::cout << "Let's go!\n";

    std::cout << " =========================================================== \n";

    for (; mktime(&date) < end_date; ++date.tm_mday) {

        std::cout << "Defining the new date... \n";

        char year[16];
        char month[16];
        char day[16];

        strftime(year, sizeof(year), "%Y", &date);
        strftime(month, sizeof(month), "%m", &date); // %m writes month as a decimal number (01-12)
        strftime(day, sizeof(day), "%d", &date);

        std::cout << "New date defined! \n";

        std::cout << "Year: " << year << "\n";
        std::cout << "Month: "<< month << "\n";
        std::cout << "Day: "<<  day << "\n\n";

        std::cout << "Make the url dynamic: \n";

        std::string url = "https://barbaraperes.com////__.csv";
        // https://barbaraperes.com/2017/08/31/2017_08_31.csv

        std::string str1 = year;
        std::string str2 = month;
        std::string str3 = day;

        url.insert(25, str1);
        url.insert(30, str2);
        url.insert(33, str3);
        url.insert(36, str1);
        url.insert(41, str2);
        url.insert(44, str3);

        std::cout << "This is the dynamic url: " << url << "\n\n";

    std::cout << " =========================================================== \n";
    }

    std::cout << " =========================================================== \n";

}   

Он работает нормально, пока день не достигнет 31, как мы можем видеть на следующем изображении

Output

Как только день достигает 31 (конец первого месяца, которыйв июле), он начнет печатать пустые дни, и месяц не изменится на 08 (август)

Output_no_day

Как мы можем решить эту проблему?

Ответы [ 2 ]

3 голосов
/ 28 октября 2019

Вот как вы можете сделать шаг вперед. Это печатает 400 дней, начиная с 2007/07 / 01.

#include <cstring>
#include <ctime>
#include <iostream>

int main() {
    std::tm date{};

    date.tm_year = 2007 - 1900; // tm_year (int) years since 1900
    date.tm_mon = 6;            // tm_mon (int) months since January (0-11)
    date.tm_mday = 1;           // tm_mday (int) day of the month (1-31)
    date.tm_hour = 12;          // mid day

    std::time_t current = std::mktime(&date);

    for(int i = 0; i < 400; ++i) {
        std::memcpy(&date, std::localtime(&current), sizeof(date));

        std::cout << date.tm_year + 1900 << " " << date.tm_mon + 1 << " " << date.tm_mday << "\n";

        current += 60 * 60 * 24; // add one day
    }
}

И вот более интересная версия с поддержкой для создания ваших URL: s на лету:

#include <cstring>
#include <ctime>
#include <iostream>

struct mytm : std::tm {        // inherit "tm" to extend it a little
    mytm(int year, int month, int day) : tm{}, current{} {
        tm_year = year - 1900;
        tm_mon = month - 1;
        tm_mday = day;
        tm_hour = 12;
        current = std::mktime(this);
    }

    void add_days(int days) {
        current += days * 60 * 60 * 24;
        std::memcpy(this, std::localtime(&current), sizeof(std::tm));
    }

    std::string strftime(const char* format, std::size_t bufsize = 64) {
        std::string retval(bufsize, ' ');
        std::size_t len = std::strftime(&retval[0], retval.size(), format, this);
        retval.resize(len);
        return retval;
    }

    std::time_t current;
};

int main() {
    mytm date(2007, 7, 1);

    for(int i = 0; i < 400; ++i) {
        std::string url =
            date.strftime("https://barbaraperes.com/%Y/%m/%d/%Y_%m_%d.csv", 51);
        std::cout << url << "\n";
        date.add_days(1);
    }
}
1 голос
/ 28 октября 2019

Вы увеличиваете день после оценки состояния цикла, и все же вы полагаетесь на вызов mktime () в условии цикла, чтобы нормализовать ваше время.

Первое, что вы должны сделать после увеличениядень - это вызов mktime для нормализации времени.

   for (; mktime(&date) < end_date; ++date.tm_mday) {
      mktime(&date);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...