【问题标题】:Parsing fields from stdin in C++在 C++ 中从标准输入解析字段
【发布时间】:2016-11-01 02:21:24
【问题描述】:

如果我有stdin 输入如下:

2014-01-23,  AA, 20
2014-05-30,  BB,2    //notice that I might have optional space
2015-03-24, CC,   5
//...
//... and so on 

如何用 C++ 编写一个程序来有效地解析 monthyear 以及后续字段?我真的被这个解析问题困住了。

我想对后续字段执行的操作将AA, 20 存储为地图。所以map[AA]=20等等。

我可以自己做。但我不知道如何阅读和解析它。 请帮忙。


尝试:

int year, month;
int  num;
string key;
map<string, int> mapping;
string s;
getline(cin,s, '-'); 
year=stoi(s); 
getline(cin,s, '-');
month=stoi(s); 
getline(cin,s, ',');
//reading the AA, BB, CC field;
getline(cin,s, ',');
for (int i=0; i<s.size(); i++);
   if (s[i]==' ') s.erase(i,1);
key=s;
//now, reading the number field following AA,BB, CC
getline(cin,s,'\n');
for (int i=0; i<s.size(); i++);
   if (s[i]==' ') s.erase(i,1);
num=stoi(s);
mapping[key]=num;

【问题讨论】:

  • 你需要一步一步来。首先,编写一个程序,读取每一行文本,一次一行。第二步:将每一行文本解析为单独的字段。第三步:将第一个字段解析为它的组成部分,年、月和日。问题解决了。看看这有多容易?
  • 是的,这很容易。但是我的代码有点长。
  • 有一句古老的 Vulcan 谚语:代码越长,越有可能出现错误。
  • 只是需要帮助才能弄清楚

标签: c++ string parsing


【解决方案1】:

另一种选择是使用std::regex(如果您使用的是“古老”编译器,则使用Boost.Regex

匹配这条线

(\d{4})\-(\d{2})\-(\d{2}),\s*(.+),\s*(.+)

然后分别从匹配组\1、\2、\3、\4、\5中获取年、月、日、第一个字段、第二个字段

【讨论】:

  • 如果我有非常大量的数据(很多行要读取),您认为这种方法仍然有效吗?
  • 视情况而定。唯一知道的方法是对其进行基准测试。编译后的正则表达式可以重复使用,因此具有相当好的性能,并且可以像固定解析器那样轻松更改
  • 这可能是一个愚蠢的问题。如何将\d{4})-(\d{2})-(\d{2}),\s*(.+),\s*(.+) 与正则表达式一起使用?
  • learn about regex 先使用regex_search or regex_match 就像例子中一样
【解决方案2】:

here 使用std::basic_string::find 给出了类似问题的答案。您可以使用-, 作为分隔符。

【讨论】:

    【解决方案3】:

    试试这个:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
        string s;
        char c;
        int x;
        cin >> s >> c >> x;
        s = s.substr(0,s.length() - 2);
        cout << s << " " << c << " " << x << endl;
        return 0;
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    相关资源
    最近更新 更多