1

I have to read in a string from std::cin in my program. The lines from cin are in the format of two numbers followed by a colon, another two numbers followed by a colon, and then a straight line. Then, the same string would be repeated. An example:

00:33:11|22:55:22

and then I would want two ints a and b to be: a = 3311 b = 225522

I'm trying to find the best way to extract the numbers from the first numbers before the straight line and store that into an int, and do the same for the second set of numbers.

I'm a little unfamiliar with c++, but I have thought about making a for loop, storing characters into a char array, and then using atoi on that array. However, I feel that this method is not the most elegant of approaches. Any suggestions to this problem?

thanks

SnG
  • 362
  • 1
  • 5
  • 18
  • @πάνταῥεῖ You were too quick on the trigger. I don't think this is a duplicate. – Neil Kirk Mar 30 '15 at 03:31
  • this is indeed not a duplicate! the reason is because the string isn't inclusively integers. – SnG Mar 30 '15 at 03:32
  • @NeilKirk Probably. It's about parsing the numbers. Anyway even for this case there's a number of duplicates available from SO. – πάντα ῥεῖ Mar 30 '15 at 03:33
  • Are you familiar with the boost library? Are you using C++03 or are you using a newer standard? – Drew Dormann Mar 30 '15 at 03:34
  • @DrewDormann i am not familiar with boost library, but i specifically can not use boost. i am also using c++11 – SnG Mar 30 '15 at 03:35
  • I'm a little wary of this question, since you seem to know how to do it - but you want to judge which answer is "most elegant". There are a broad number of approaches, but the most elegant one would be a matter of opinion. – Drew Dormann Mar 30 '15 at 03:38
  • @sg123456 Here are some useful hints how it can be done: [How to test whether stringstream operator>> has parsed a bad type and skip it](http://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it) – πάντα ῥεῖ Mar 30 '15 at 03:42
  • 2
    I agree with @DrewDormann. I think it would be best to define "elegant", if you want to make it a beauty pageant it's not a good place. If by elegant you mean best in terms of time/space complexity it would be better. I also would understand the urge to write it in proper modern c++ idioms. It's hard if you are not familiar with it. Perhaps best way it to write something that works, and put it on codereview. At least it would show some effort rather than being possible to interpret as "Write me some code, i'll take the prettiest one." – luk32 Mar 30 '15 at 03:50

2 Answers2

1

You could use std::istringstream and std::getline() to help you with that:

#include <string>
#include <sstream>
#include <iomanip>

int timeStrToInt(const std::string &s)
{
    std::istringstream iss(s);
    char colon1, colon2;
    int v1, v2, v3;

    if ((iss >> std::setw(2) >> v1 >> colon1 >> std::setw(2) >> v2 >> colon2 >> std::setw(2) >> v3) &&
        (colon1 == ':') && (colon2 == ':'))
    {
        return (v1 * 10000) + (v2 * 100) + v3;
    }

    // failed, return 0, throw an exception, do something...
}

void doSomething()
{
    //...

    std::string line = ...; // "00:33:11|22:55:22"

    std::istringstream iss(line);
    std::string value;

    std::getline(iss, value, '|');
    int a = timeStrToInt(value);

    std::getline(iss, value);
    int b = timeStrToInt(value);

    //...
}

Personally, I would use sscanf() instead:

#include <cstdio>

std::string line = ...; // "00:33:11|22:55:22"

int v1, v2, v3, v4, v5, v6;
if (std::sscanf(line.c_str(), "%02d:%02d:%02d|%02d:%02d:%02d", &v1, &v2, &v3, &v4, &v5, &v6) == 6)
{
    int a = (v1 * 10000) + (v2 * 100) + v3;
    int b = (v4 * 10000) + (v5 * 100) + v6;
    //...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Try scanning in integers, and scanning and ignoring the separator characters. Then use some multiplication to get your number. In your case, try this:

int a;
char b;
int result = 0;
cin >> a;
result += a*10000;
cin >> b;
cin >> a;
result += a*100;
cin >> b;
cin >> a;
result += a;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
acenturyandabit
  • 1,188
  • 10
  • 24