0

Possible Duplicate:
How to split a string in C++?
C++ split string

How I can split a line, shown below, in C++ from a file?

I want to save the result of game output that has the following format:

CFC 1 - 0 RES

I have four variables:

string team1;
string team2;
int goalst1;
int goalst2;

How can I split the string so that each corresponding part is in the above four variables?

Community
  • 1
  • 1
franvergara66
  • 10,524
  • 20
  • 59
  • 101

4 Answers4

5
string team1;
string team2;
int goalst1;
int goalst2;
string dash;
std::cin >> team1 >> goalst1 >> dash >> goalst2 >> team2;
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • The input is not standard input. Is a line read from a file using getline function, which is stored in a variable of type string, I want to know how to split the string in order to have these values ​​in the variables – franvergara66 Jul 14 '12 at 04:31
3

You could do something like this which requires #include <sstream>:

char trash;

std::stringstream mystream(myInputString);

mystream >> team1 >> goalst1 >> trash>> goalst2 >> team2;

or

char trash;

std::stringstream mystream;
mystream << myInputString;

mystream >> team1 >> goalst1 >> trash>> goalst2 >> team2;

Edit: This is more advanced but kinda neat. Stick this in a header:

#include <iostream>
#include <string>
#include <array>
#include <cstring>

template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
        std::array<e, N-1> buffer; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(&buffer[1], N-2); //read the rest
        if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
        e buffer;  //get buffer
        in >> buffer; //read data
        if (buffer != cliteral) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
        return std::operator>>(in, carray);
}
template<class e, class t, class a>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, a& obj) {
        return in >> obj; //read data
}

This allows you to do string literals in streams:

std::stringstream mystream(myInputString);

mystream >> team1 >> goalst1 >> '-' >> goalst2 >> team2;

or

std::stringstream mystream;
mystream << myInputString;

mystream >> team1 >> goalst1 >> '-' >> goalst2 >> team2;

See also: Safer but easy-to-use and flexible C++ alternative to sscanf()

Community
  • 1
  • 1
Drise
  • 4,310
  • 5
  • 41
  • 66
  • The input is not standard input. Is a line read from a file using getline function, which is stored in a variable of type string, I want to know how to split the string in order to have these values ​​in the variables – franvergara66 Jul 14 '12 at 04:31
1

If I get it right, u are probably trying to read from a file. Use ifstream then, and you can read from a file just like you read from a standard input like cin.

i.e.

  ifstream myfile("filename");

Now use myfile instead of cin operator and you are done..

bhuwansahni
  • 1,834
  • 1
  • 14
  • 20
0

I like boost::split for that kind of job:

#include <string>
#include <vector>

#include <boost/algorithm/string/split.hpp>

struct Result {
     std::string team1;
     std::string team2;
     unsigned goals1;
     unsigned goals2;
};

Result split(std::string const& s) {
    std::vector<std::string> splitted;
    boost::split(s, splitted, boost::token_compress_on);

    if (splitted.at(2) != "-") {
        throw runtime_error("The string format does not match");
    }

    Result r;
    r.team1 = splitted.at(0);
    r.team2 = splitted.at(4);
    r.goals1 = stoi(splitted.at(1));
    r.goals2 = stoi(splitted.at(3));

    return r;
}
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722