Hello
I need the user to input for example a time format HH:MM(AMorPM) or a complex number format: X+jY

Then I want to read HH in and int and MM in another int
and the same for the complex number example.

I am aware I should use delimiters, but i dont know what to do, any help will be appreciated

Recommended Answers

All 21 Replies

Look at the time input validation stuff and try to adopt it for complex number input (and other user types):

struct Time {
    int hh, mm;
    std::string ampm; // "AM" or "PM"
};

bool getTime(std::istream& is, Time& t)
{
    bool res = false;
    char c;
    if (is >> t.hh) { // true if it's a number
        if (is.get(c) && c == ':' && (is >> t.mm)) { // :MM here
            if ((is >> t.ampm) && (t.ampm == "AM" || t.ampm == "PM")) {
                // Check up hh & mm values
                if (t.hh >= 0 && t.hh <= 12 && t.mm >= 0 && t.mm < 60)
                    res = true; // good time value
            }
        }
    } 
    return res;
}
// Advanced (syntax sugar):
std::istream& operator>>(std::istream& is, Time& t) {
    if (!getTime(is,t))
        is.setstate(std::ios::failbit);
    return is;
}
std::ostream& operator<<(std::ostream& os, const Time& t) {
    os << t.hh << ':' << t.mm << ' ' << t.ampm;
    return os;
}

However this approach has a serious defect in the console input environment. If the user types a part of a valid time value only then getTime waits the rest of Time value. It seems like you program hangs. Possible workaround: read a line then use istringstream:

bool GetTime(Time& t)
{
    bool res = false;
    std::string line;
    if (std::getline(std::cin,line)) {
        std::istringstream is(line);
        res = getTime(is,t);
    }
    return res;
}

Of course, it's not a reference implementation. Sorry but I have no time to prepare Program Logic Manual for this improvisation ;)...

I had that first method in a book.

But i have a question:
how does the program know how many characters are hh and mm and so on

we fist tell it if(cin>>hh) will that work whether the user inputs 10:40 or 2329:40?

I will check for it to be between 0 and 12, but the thing I mean is how can it tell that it will stop before the ":"

Another option would be to use boost libraries and regex to evaluate a correct time. It would save a lot of messing around as ArkM has demonstrated. :P

For example:
http://binaryelves.wordpress.com/2008/08/28/regular-expressions-time-hhmm-validation-24-hours-format/

I am not doing it for the time, I want to learn the method, the time is just an example.

Would appreciate if someone tell me what tells the program to stop reading hh before the delimiter when i use

if (cin>>hh>

Member Avatar for iamthwee

Nah look at the link below kiddo:
http://www.daniweb.com/forums/post140537-2.html

Then you separate them into to arrays.

array[0]
array[1]

Then go through all the rules, so you ensure you get valid times.

Nah look at the link below kiddo:
http://www.daniweb.com/forums/post140537-2.html

okay, this is alot easier, but this will get all of them as strings, i want to be able to extract some as strings, some as chars and some as intergers and doubles
and i also want them to be into different variables, not just one, like token for example

and is the std:: instead of using namespace std ??

okay, i dont get the last part you added to your post, about the arrays, how can i extract different types as I specified, and keep them in different variables

Member Avatar for iamthwee

Pretty simple really, to convert a string to an int etc, just use stringstreams.

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046996179&id=1043284385

You don't really need to use single chars here.


And if you use a vector instead of an array you just build the values on the fly as you go. Although you could use a dynamic array, but that's gay in my opinion.

okay, and what you meant by the arrays

you mean instead of the while with the token,

i make it like getlink(iss, token, :) ????

is that what you mean?
btw, i never used stringstreams, and i dont even know what is iss :)

Member Avatar for iamthwee

>btw, i never used stringstreams, and i dont even know what is iss

Yeah well, you learn something new tous le jour and such and such.

yes, i agree, but you didnt answer my question about the arrays

Member Avatar for iamthwee

Well personally I'd use a vector:

vissssssssssssssssssss

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;

int main()
{

   vector <string> array; 
 
   string tmp = "12:20";
   string token;
   istringstream iss(tmp);
   while ( getline(iss, token, ':') )
   {
      array.push_back(token);
   }   
   cout <<array[0] <<endl;
   cout <<array[1] <<endl;
   
   cin.get();
}

i think i will have to

vector<int> array


in order for that to work, correct?

Member Avatar for iamthwee

I guess, but I'm just conjecturing here.

I was thinking you might get into trouble with times such as "03:45" but maybe stringstream converts the "03" to 3 anyhoo.

Don't quote me on that.

very good,

but i am not quite getting istringstream, i got its to input the stream, and does iss has anything to do with it?

Member Avatar for iamthwee

Post your code...

what code?
I mean the one you made, this one:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;

int main()
{

   vector <string> array; 
 
   string tmp = "12:20";
   string token;
   istringstream iss(tmp);
   while ( getline(iss, token, ':') )
   {
      array.push_back(token);
   }   
   cout <<array[0] <<endl;
   cout <<array[1] <<endl;
   
   cin.get();
}
Member Avatar for iamthwee

Is that a joke? No the bit where you're not quite getting the istringstream?

Post an example of what you've tried, state what you expect, and what you're unsure of.

by "I am not getting istringstream"

I mean i dont understand it, and i dont know what it does.

>how does the program know how many characters are hh and mm and so on
>we fist tell it if(cin>>hh) will that work whether the user inputs 10:40 or 2329:40?
>I will check for it to be between 0 and 12, but the thing I mean is how can it tell that it will stop before the ":"
The overloaded operator>>(istream&,int&) stops to extract characters from a stream when integer representation ended. Obviously, the colon is not a part of integer. That's all. The next get(char&) extracts stop-char and we can compare it with desired colon char.
We will check hours and minutes after input operations ended (see line #14 in my snippet above):

line #14:
if (t.hh >= 0 && t.hh <= 12 && t.mm >= 0 && t.mm < 60)

>by "I am not getting istringstream" ... I mean i dont understand it, and i dont know what it does.
http://www.deitel.com/articles/cplusplus_tutorials/20060211/index.html
Well, pay attention to getTime; no stringstreams in this (working ;)) function.

You asked a general question about input data validation. Be ready to get general answers ;)...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.