简体   繁体   English

在C ++中解析日期字符串

[英]Parsing a date string in C++

My son is learning C++ and one of his exercises it to have the user input a date in DD/MM/YYY and then output it to Month day, year 我儿子正在学习C ++,他的一项练习是让用户以DD / MM / YYY输入日期,然后将其输出到年月日

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

I am trying to help him understand the various ways but now I have confused myself. 我试图帮助他理解各种方式,但现在我感到困惑。

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

I can't figure it out with any of these quite right. 我无法用所有这些正确的方法弄清楚。

my current attempt to parse is: 我目前的解析尝试是:

#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;
    }
}

but I am getting errors like: 但我收到如下错误:

`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`
int day, month, year;
char t;
std::cin >> day >> t >> month >> t >> year;

You've missed the std Regular Expressions Library ! 您已经错过了std正则表达式库 I reckon it's the safest and most effective way of doing this. 我认为这是最安全,最有效的方法。

Back on topic, I think that since getline is an extern "C" function, you can't overload it using a using namespace std (which should be banned by the way). 回到主题上,我认为既然getline是一个extern "C"函数,则不能使用using namespace std (应予以禁止)重载它。 You should try prepending std to all getline calls. 您应该尝试在所有getline调用之前添加std

For std::istringstream , you need: 对于std::istringstream ,您需要:

#include <sstream>

PS Don't use using namespace std; PS不要using namespace std; . It's a bad habit, and it will eventually get you into trouble. 这是个坏习惯,最终会惹上麻烦。

The error 错误

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

means the compiler couldn't make sense of this line: 意味着编译器无法理解这一行:

while (getline(date, line))

Both date and line are declared as std::string and there's no overload of getline that takes two strings. dateline都声明为std::string并且getline不会重载两个字符串。 Compiler guessed that you were trying to call this function that is not part of C++ library (apparently, one of standard library headers includes stdio.h which is where that function is coming from). 编译器猜测您正在尝试调用不属于C ++库的该函数 (显然,标准库头文件之一包含stdio.h ,该函数来自于此 )。

The error 错误

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

means the compiler doesn't know what std::istringstream is. 意味着编译器不知道什么是std::istringstream You forgot to include <sstream> . 您忘记了包含<sstream>

If you want to extract lines from a string by means of std::getline , you need to put it in a stringstream first, just like you do inside the loop. 如果要通过std::getline从字符串中提取行,则需要先将其放入字符串流,就像在循环中一样。

Parsing dates isn't that easy. 解析日期不是那么容易。 You don't want the user to be able to enter 44/33/-200 and get away with it. 您不希望用户能够输入44/33/-200并摆脱它。 How I'd might approach this: 我将如何处理这个问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM