【问题标题】:Parsing a date string in C++在 C++ 中解析日期字符串
【发布时间】:2013-02-19 20:25:50
【问题描述】:

我儿子正在学习 C++,他的一个练习是让用户在 DD/MM/YYY 中输入日期,然后将其输出到月日、年

So: 19/02/2013
Output: February 19, 2013.

我正在努力帮助他理解各种方式,但现在我自己都搞糊涂了。

getline() std::string::substr() std::string::find() std::string::find_first_of() std::string::find_last_of()

我无法用这些完全正确的方式弄清楚。

我目前的解析尝试是:

#include <iostream>
#include <string>

using namespace std;

int main (void)
{
    string date;
    string line;

    cout << "Enter a date in dd/mm/yyyy format: " << endl;
    std::getline (std::cin,date);

    while (getline(date, line))
    {
        string day, month, year;
        istringstream liness( line );
        getline( liness, day, '/' );
        getline( liness, month,  '/' );
        getline( liness, year,   '/' );

        cout << "Date pieces are: " << day << " " << month << " " << year << endl;
    }
}

但我收到如下错误:

`g++ 3_12.cpp -o 3_12`
`3_12.cpp: In function ‘int main()’:`
`3_12.cpp:16: error: cannot convert ‘std::string’ to ‘char**’ for argument ‘1’ to ‘ssize_t getline(char**, size_t*, FILE*)’`
`3_12.cpp:18: error: variable ‘std::istringstream liness’ has initializer but incomplete type`

【问题讨论】:

  • 你帮孩子做事并没有帮助他。
  • 感谢 Austin,但他也坐在我旁边查看文档以解决这个问题。所以我称之为团队合作
  • 我可以补充一下,这是他放学的一周,所以也是课外活动。
  • size_t getline(char**, size_t*, FILE*)POSIX function。我不认为试图称呼它是你的意图,或者是吗?
  • @AustinMullins 和孩子们一起工作是一种极大的乐趣。

标签: c++ string parsing date


【解决方案1】:
int day, month, year;
char t;
std::cin >> day >> t >> month >> t >> year;

【讨论】:

  • 这不是一个有趣的方式!
  • @Jason 我认为它是唯一的(在提出的一种方式中):/,正则表达式和std::strings 和std::getline一样是OVERKILL
  • Regex 您可以免费获得验证。由于短字符串优化,std::string 在大多数实现中都是免费的。
  • @AlexChamberlain 在什么情况下是免费的,它在计算上肯定不便宜。一个好的正则表达式的复杂性可以更容易地在代码中模拟出来。
  • 坦率地说,我们在这里谈论的不是低延迟的小技巧,而是为年轻程序员提供的一般性编程建议。字符串的 C++ 习语是std::string,在大多数情况下几乎是免费的。正则表达式对于许多问题都非常强大,这是一个很棒的应用程序。
【解决方案2】:

您错过了std Regular Expressions Library!我认为这是最安全、最有效的方法。

回到主题,我认为因为getline 是一个extern "C" 函数,你不能使用using namespace std 重载它(顺便说一句应该禁止)。您应该尝试在所有 getline 调用之前添加 std

【讨论】:

  • 关于using namespace std; 的优点这是我的快速尝试。硬件确实做到了std:: 的更好方式
【解决方案3】:

对于std::istringstream,您需要:

#include <sstream>

附:不要使用using namespace std;。这是一个坏习惯,最终会给你带来麻烦。

【讨论】:

    【解决方案4】:

    错误

    3_12.cpp:16: error: cannot convert ‘std::string’ to ‘char**’ for argument ‘1’ to ‘ssize_t getline(char**, size_t*, FILE*)’

    表示编译器无法理解这一行:

    while (getline(date, line))
    

    dateline 都被声明为 std::string 并且没有 getline 的重载 需要两个字符串。编译器猜测您试图调用不属于 C++ 库的 this function(显然,标准库头文件之一包括 stdio.h,这是该函数的来源)。

    错误

    3_12.cpp:18: error: variable ‘std::istringstream liness’ has initializer but incomplete type

    表示编译器不知道std::istringstream 是什么。你忘了包括&lt;sstream&gt;

    如果你想通过std::getline从字符串中提取行,你需要先把它放在一个字符串流中,就像你在循环中做的那样。

    解析日期并不容易。您不希望用户能够输入 44/33/-200 并侥幸逃脱。我会如何处理这个问题:

    std::istringstream iss(date); // date is the line you got from the user
    
    unsigned int day, month, year;
    char c1, c2;
    
    if (!(iss >> day >> c1 >> month >> c2 >> year)) {
        // error
    }
    if (c1 != '/' || c2 != '/') { /* error */ }
    if (month > 12) { /* error  / }
    
    // ... more of that, you get the idea
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      • 2011-07-21
      • 2012-07-21
      • 1970-01-01
      相关资源
      最近更新 更多