首页 > 解决方案 > 使用 C++ 打开动态 URL

问题描述

得到以下 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,我们可以在下一张图片中看到

输出

一旦日期达到 31(第一个月的月底,即 7 月),它将开始打印空天,月份不会更改为 08(8 月)

输出_no_day

我们如何解决这个问题?

标签: c++dateurliteration

解决方案


以下是您可以如何向前迈进的方法。这将打印 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);
    }
}

推荐阅读