如何阅读这些输入? A,1,BC,2

时间:2017-04-04 09:00:20

标签: c++ parsing input scanf

我开始在像hackerrank / hackerearth这样的网站上工作。在那里我发现了一个提取输入的问题。它很容易用Java。

考虑一个非常简单的读取输入和显示它的问题: 流程就像:

read A
repeat A times
      read X1,N1,X2,N2 ; where Xi is any string, Ni is any integer.
      display X1+X2, N1+N2

我不知道如何阅读X1,N1,X2,N2,其中X1和X2是字符串,我也尝试了但问题是,当我读取第一个字符串时,它读取整行,例如当我读了它应该是X1的字符串,但它是X1,N1,X2,N2。我使用的代码是

scanf("%s,%d,%s,%d", x1, &n1, x2, &n2)

提前感谢,抱歉我的英语不好。

更新#1:

示例行:

3
some,123,thing,456
something,579
a,1,b,2
ab,3
hello,100,world,100
helloworld,200

2 个答案:

答案 0 :(得分:2)

我认为你正在寻找这样的东西:

int number_of_inputs;
std::cin >> number_of_inputs;
for (int iteration = 0; iteration < number_of_inputs; ++iteration){
    int integer1, integer2;
    string string1, string2, stupid_comma;
    std::cin >> string1 >> stupid_comma >> integer1 >> stupid_comma >> string2 >> stupid_comma >> integer2;
    std::cout << string1 << " + " << string2 << " = " << integer1+integer2 << std::endl; 
}

edit2:在op提供输入后,我的代码不正确。请检查此答案:Parsing a comma-delimited std::string

edit3:替代拆分方法op需要:

std::vector<std::string> split(const std::string &text, char sep, int num)
{
    std::vector<std::string> tokens;
    std::size_t start = 0, end = 0;
    int elements = 0;

    while ((end = text.find(sep, start)) != std::string::npos) {
        if ( elements == num) break;

        tokens.push_back(text.substr(start, end - start));
        start = end + 1;
        elements++;
    }

    tokens.push_back(text.substr(start));
    return tokens;
}

edit4:使用拆分功能的新代码:

int number_of_inputs;
std::cin >> number_of_inputs;
for (int iteration = 0; iteration < number_of_inputs; ++iteration){
    std:string line;
    cin >> line;
    int integer1, integer2;
    string string1, string2, stupid_comma;
    std::vector<std::string> my_line = split(line, ',', 4);
    string1 = my_line[0];
    string2 = my_line[2];
    integer1 = stoll(my_line[1], nullptr, 10);
    integer2 = stoll(my_line[3], nullptr, 10);
    std::cout << string1 << " + " << string2 << " = " << integer1+integer2 << std::endl; 
}

答案 1 :(得分:1)

以下是使用std::regex的解决方案,即使它比接受的答案更长,我发现它更清晰,更灵活。

#include <iostream>
#include <string>
#include <regex>

using namespace std;

struct MyPair {
    string x; int n;

    MyPair() {}
    MyPair( const string& x, int n )
        : x(x), n(n) {}
};

void parse_line( const string& str, MyPair& p1, MyPair& p2 ) {

    typedef regex_iterator<string::const_iterator> re_iterator;
    typedef re_iterator::value_type re_iterated;

    regex re("(\\w+),(\\d+),(\\w+),(\\d+)");
    re_iterator rit( str.begin(), str.end(), re );
    re_iterator rend;

    if ( rit != rend ) {
        p1 = MyPair( (*rit)[1], stoi((*rit)[2]) );
        p2 = MyPair( (*rit)[3], stoi((*rit)[4]) );
    }

}

int main() {

    int A = 0;
    while ( A <= 0 ) {
        cin >> A;
    }

    string line;
    MyPair p1, p2;

    for ( int i = 0; i < A; i++ ) {
        cin >> line;
        parse_line( line, p1, p2 );
        cout << (p1.x + p2.x) << " " << (p1.n + p2.n) << endl;
    }

}

注意它使用C ++ 11中的功能,所以为了使用clang++编译它(例如),你应该这样做:

clang++ -std=c++11 file.cpp -o file