【问题标题】:Open a dynamic URL using C++使用 C++ 打开动态 URL
【发布时间】:2019-10-07 23:37:18
【问题描述】:

得到以下网址 - https://barbaraperes.com/2017/08/31/2017_08_31.csv,即 2017 年、08 月和 31 日。

目前,我正在构建一个脚本,该脚本会从给定时刻到现在经历所有的日子、几个月和几年。对于每一天,脚本都会更改一个 url(字符串),插入日期、月份和年份,以及 opens it

这是当前代码

#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 月)

我们如何解决这个问题?

【问题讨论】:

  • 作为输出得到Exmplr 经过眼睛调试后,我得到了axmplr。 ;-) 但是我学习太累了 并不是说​​计算机编程很容易(总是)——这是一项艰巨的工作,有时让我头晕目眩(尽管我的妻子仍然认为我一直坐着在我办公室的日子,一直在玩电脑)。保持冷静,睡个好觉,振作起来,并与之抗争。是的你可以。 (您在 Q 中提出的内容实际上就像一个计划。按照它来。)
  • 是的,你是对的,axmplr。我用Exmplr 做了另一个练习;)
  • 您面临的挑战究竟是什么?您遇到的具体问题是什么?更一般的,请关注How to Ask。另外,累了就睡一觉吧。你会犯更多的错误而不是修复,你实际上是通过在梦中处理它来学习东西。
  • 问题是如何让url动态化。
  • 问题是如何让url动态化。动态是什么意思?根据您现有的代码,您在运行时构建 URL。恕我直言,这是必要的动态。一旦您在特定日期完成了它,下一步可能是将该代码包装在一个循环中以迭代日期(如您的第二句话中所描绘的)。

标签: c++ date url iteration


【解决方案1】:

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

【讨论】:

  • 无法编译最后的代码,我在第 21 行第 53 列收到 [Error] invalid conversion from 'const char*' to 'char*' [-fpermissive]
  • 还有[Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11 在第 6 行,第 44 和 55 列。
  • 好的,我已经修复了第一个错误,您可以再次尝试复制。我假设 C++17,但似乎您使用的是旧版本。你到底用的是什么版本?
  • @BárbaraPeres 没关系 :-) 编译器通常有一个选项让您选择您想要使用的 C++ 版本,但如果它真的很旧,您可能没有该选项。我自己没有使用过 Dec-C++。
  • 这个没有,据我所知...再次感谢您的关注和关心,您让我很开心:)
【解决方案2】:

您在评估循环条件后的第二天递增,但您依赖循环条件中对 mktime() 的调用来标准化您的时间。

增加一天后你应该做的第一件事是调用 mktime 来标准化时间。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    相关资源
    最近更新 更多