【问题标题】:How to a sub-string from middle of a string如何从字符串中间获取子字符串
【发布时间】:2019-08-11 03:36:43
【问题描述】:

我有一个字符串“YYYY-MM-DD”,想将该字符串转换为整数并将它们分别存储为年、月、日。我用substr 得到了年份,但我无法得到 MM 和 DD。

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

int dayOfYear(string date)
{
    for (int i = 0; i < date.size(); i++)
    {
        if (date[i] == '-')
            date.erase(date.begin()+i);
    }
        //getting substring for year
    string str1 = date.substr(0, 4);

    string str2 = date.substr(5, 6);//getting wrong output

        //converting string to int
    int year = stoi(str1);
    int month = stoi(str2);

    return month;//getting output as 109


}

int main()
{
    string date = "2019-01-09";
    int p = dayOfYear(date);
    cout << p;
    return 0;
}

【问题讨论】:

    标签: c++ string data-structures


    【解决方案1】:

    您没有正确使用std::string::substr()。您给它两个索引(以及错误的索引),但它需要一个索引和一个计数。

    不需要erase()- 字符(此外,您的循环无论如何都会中断,因为您没有在每个erase() 之后重新调整i,所以您正在跳过字符)。您可以使用std::string::find() 查找- 字符的索引,然后使用这些索引计算std::string::substr() 所需的值。

    int yearOfDate(std::string date)
    {
        size_t ends = date.find('-');
        //getting substring for year string
        string str = date.substr(0, end);
        //converting string to int
        return std::stoi(str);
    }
    
    int monthOfDate(std::string date)
    {
        size_t start = date.find('-') + 1;
        size_t end = date.find('-', start);
        //getting substring for month string
        string str = date.substr(start, end - start);
        //converting string to int
        return std::stoi(str);
    }
    
    int dayOfDate(std::string date)
    {
        size_t start = date.find('-');
        start = date.find('-', start + 1) + 1;
        //getting substring for day string
        string str = date.substr(start);
        //converting string to int
        return std::stoi(str);
    }
    
    int main()
    {
        string date = "2019-01-09";
        int y = yearOfDate(date);
        int m = monthOfDate(date);
        int d = dayOfDate(date);
        std::cout << y << ' ' << m << ' ' << d;
        return 0;
    }
    

    由于您使用的是 C++11 或更高版本(由于使用了std::stoi()),请考虑改用std::get_time()

    #include <sstream>
    #include <iomanip>
    #include <ctime>
    
    int main()
    {
        string date = "2019-01-09";
        std::tm t = {};
        std::istringstream(date) >> std::get_time(&t, "%Y-%m-%d");
        int y = tm.tm_year + 1900;
        int m = tm.tm_mon + 1;
        int d = tm.tm_mday;
        std::cout << y << ' ' << m << ' ' << d;
        return 0;
    }
    

    在 C++20 中,您可以使用 std::chrono::from_stream(std::chrono::year_month_day) 代替:

    #include <sstream>
    #include <chrono>
    
    int main()
    {
        string date = "2019-01-09";
        std::istringstream iss(date);
        std::chrono::year_month_day ymd;
        std::from_stream(iss, "%Y-%m-%d", ymd);
        unsigned y = ymd.year();
        unsigned m = ymd.month();
        unsigned d = ymd.day();
        std::cout << y << ' ' << m << ' ' << d;
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      string::substr 的第二个参数应该是计数——返回的字符串中包含的字符数。

      删除- 后,date"20190109"。您需要从位置4 开始并从日期中获取2 字符。使用

      string str2 = date.substr(4, 2);
      

      【讨论】:

      • 此解决方案返回月份,但函数名为 dayOfYear()。删除- 字符后,日期改为date.substr(6, 2)
      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2015-11-04
      • 2015-08-21
      • 1970-01-01
      相关资源
      最近更新 更多