-3

In C++, I'd like to read from an input file which contains different kind of datas: first the name of a contestant (2 or more strings with whitespaces), then an ID (string without whitespaces, always beginning with a number), then another strings without ws and a numbers (the sports and their achieved places).

For example:

Josh Michael Allen 1063Szinyei running 3 swimming 1 jumping 1

I show you the code what I started to write and then stucked..

void ContestEnor::next()
{
    string line;
    getline(_f , line);
    if( !(_end = _f.fail()) ){
        istringstream is(line);
        is >> _cur.contestant >> _cur.id; // here I don't know how to go on
        _cur.counter = 0;
        //...
    }
}

Thank you for your help in advance.

πάντα ῥεῖ
  • 83,259
  • 13
  • 96
  • 175
chuck
  • 63
  • 9
  • Not entirely sure what you are asking here. It seems to me like you want to get "Josh Michael Allen" into `_cur.contestant`. C++'s IOstreams don't offer a tool to do this without a unique delimiter, and spaces in the name **and** between the tokens strips the delimiter of uniqueness. With "Josh Michael Allen|1063Szinyei|running 3|swimming 1|jumping 1" you could use `getline(is, `_cur.contestant, '|');` to split on the unique delimiter. Change the storage protocol if you can to allow this. It's much simpler. – user4581301 Mar 28 '19 at 18:00
  • If you cannot... If there is a fixed number of sports you could start at the end, consume backwards to read the the sports, then the ID and the remainder must be the contestant's name. If you don't know how many sports there could be, You have to pray that the contestant's name contains no numbers. Scan from the beginning of the string until you find a token that matches the signature of an ID. Store the ID. Everything before the ID is part of the name. Store it. Everything after the ID is a string-number pair. Read and store the pairs until you hit the end of the line. – user4581301 Mar 28 '19 at 18:04
  • Haha, thank you, I need to do this way, I cannot modify the input file. I had this or a bit similar idea before but since it's a homework, I need to use the file like that.. Literally had no idea how on earth. – chuck Mar 29 '19 at 17:04
  • Chuck, Second comment gives a couple possibilities. Simplest is probably the second option, scan for a token that matches the signature of an ID string. If the ID string MUST start with a number, you could look for a token that starts with a number, for example. This would fail with a name like 5usan 3radshaw, of course, making delimiters much more effective. – user4581301 Mar 29 '19 at 17:11

1 Answers1

0

You should look into using std::getline with a delimiter. This way, you can delimit on a space character and read until you find a string where the first character in a number. Here is a short code example (this seems rather homework-like, so I don't want to write too much of it for you ;):

std::string temp, id;

while (std::getline(_f, temp, ' ')) {
    if (temp[0] >= 0 && temp[0] <= '9') {
        id = temp;
    }
    // you would need to add more code for the rest of the data on that line
}

/* close the file, etc. */

This code should be pretty self-explanatory. The most important thing to know is that you can use std::getline to get data up until a delimiter. The delimiter is consumed, just like the default behavior of delimiting on a newline character. Thus, the name getline isn't entirely accurate - you can still get only part of a line if you need to.

Will Eccles
  • 365
  • 1
  • 4
  • 14
  • @user4581301 my apologies, edited. I think I was thinking of `scanf`, since I was just using C all day. Also, my justification for `getline` is that a space *can* be the delimiter, but if they changed this file to be comma-separated, it could easily be amended. The extraction operator, in this case, would operate the same way, but `getline` is more adaptable to other situations. – Will Eccles Mar 29 '19 at 14:51