Hey! Again, small but devious problem for me: I have a string that gets time as an input, in a format like "9.45" or "15.37". How do I extract the hours and minutes to integer variables, when the hour part may consist of either one or two digits? If it was just one digit from 0-9 I could just pick the chars up and convert them, but now I can't figure out the solution... :-/ Maybe I haven't had enough coffee today!

Hi

You can convert time string values with stringstream to double values. From double values you can cast hours and minutes:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){  
  stringstream conv;
  double t; int h,m;
  conv<<"9.45"; conv>>t;
  h=(int)t; m = (int)(100*(t-h)+0.5);
  cout<<t<<" = "<<h<<":"<<m<<endl;   // 9.45 = 9:45
  return 0;
}

I have choosen your "9.45" sample as constant input value for conv. You may use getline(cin, stime) to read in various strings stime and convert them by conv<<stime; conv>>t. What I liked to show is how to convert data from one datatype into another datatype using stringstream. Possibly there are shorter solutions.

-- tesu

Edited 6 Years Ago by tesuji: mount typo

Hi

You can convert time string values with stringstream to double values. From double values you can cast hours and minutes:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){  
  stringstream conv;
  double t; int h,m;
  conv<<"9.45"; conv>>t;
  h=(int)t; m = (int)(100*(t-h)+0.5);
  cout<<t<<" = "<<h<<":"<<m<<endl;   // 9.45 = 9:45
  return 0;
}

I have choosen your "9.45" sample as constant input value for conv. You may use getline(cin, stime) to read in various strings stime and convert them by conv<<stime; conv>>t. What I liked to show is how to convert data from one datatype into other datatypes using stringstream. Possibly there are shorter solutions

-- tesu

Actually, I'm not really into using double values unless I really have to. Instead, I came up with this kind of solution:

string hours, minutes;
stringstream ss(argv[4]);
getline(ss, hours, '.');
        
if(hours.length() == 1 || hours.length() == 2) {
    for(int i = 0; i < hours.length(); i++) {
        if(hours[i] >= '0' && hours[i] <= '9')
            ok4 = true;
    }
    stringstream hss(hours);
    if(hss >> hours_int)
        if(hours_int < 0 || hours_int > 23)
            ok4 = false;
                   
    cout << "hours: " << hours_int << endl;
}
if(ok4) {
    getline(ss, minutes, '.');
            
    if(minutes.length() == 1 || minutes.length() == 2) {
        for(int i = 0; i < minutes.length(); i++) {
            if(minutes[i] >= '0' && hours[i] <= '9')
                ok4 = true;
            else
                ok4 = false;
        }
        stringstream mss(minutes);
        if(mss >> minutes_int)
            if(minutes_int < 0 || minutes_int > 59) {
                ok4 = false;
                cout << "Mistake!" << endl;
            }
    }
            
    cout << "minutes: " << minutes_int << endl;
}

This does format checks for the strings and jumps over the actual tokenizing code if the input is not in correct format. I know, it's kinda long piece of a code for such a simple task, but this way, I can get the int values straight to reference variables and therefore use them in the main code, I don't have to make the tokenizing stuff again, which kinda saves some coding and time later on. :)

This question has already been answered. Start a new discussion instead.