Input time as hh:mm and no other way

Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Oct 2009
Posts: 17
Reputation: dotnabox is an unknown quantity at this point 
Solved Threads: 0
dotnabox dotnabox is offline Offline
Newbie Poster

Input time as hh:mm and no other way

 
0
  #1
Nov 5th, 2009
So my program is coming along, but now I am writing in the range checking to ensure that the inputs are actually what they should be. My code works fine for time, except for the fact that white space gets ignored. I need to ensure that a user cannot input "10: 09 AM". It must be in the format hh:mm

My code:

  1. void Time::makeAppt()
  2. {
  3. Time startTime, endTime;
  4.  
  5. cout << "Start time >>";
  6. cin >> startTime;
  7. cout << "End time >> ";
  8. cin >> endTime;
  9. }
  10.  
  11. istream &operator>>( istream &input, Time &time)
  12. {
  13. input >> time.hour;
  14. input.ignore();
  15. input >> time.minute;
  16. input.ignore();
  17. input >> time.period;
  18.  
  19. return input;
  20. }
Thank you for any suggestions you might have. =]
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 24
Reputation: boblied is an unknown quantity at this point 
Solved Threads: 9
boblied boblied is offline Offline
Newbie Poster
 
0
  #2
Nov 5th, 2009
How about using cin.get() to get one character at a time, verifying that the order is digit, digit [convert to int and check range], colon, digit, digit [convert to int and check range], end-of-line. Maybe ignore leading or trailing white space to be nice. Not sure how you're going to indicate an error -- throw an exception maybe, or just exit() after an error message?
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 17
Reputation: dotnabox is an unknown quantity at this point 
Solved Threads: 0
dotnabox dotnabox is offline Offline
Newbie Poster
 
0
  #3
Nov 5th, 2009
How would I use the cin.get() within my overloaded operator? As for the errors, well, I have to build certain messages into it and loop it back around to handle asking for the input again. I'm not worried about that part.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,837
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster
 
0
  #4
Nov 5th, 2009
Originally Posted by dotnabox View Post
How would I use the cin.get() within my overloaded operator? As for the errors, well, I have to build certain messages into it and loop it back around to handle asking for the input again. I'm not worried about that part.

If you read it in as a c-style string, you can use getline and specify 6 characters (5 + 1) maximum. Or use get () five times.

http://www.cplusplus.com/reference/i...tream/getline/

isdigit could come in handy from cctype.

http://www.cplusplus.com/reference/c...ctype/isdigit/

To use get or getline using a c-string, declare a C-string of size 6. If you want to use get, loop through, specifying the character with the loop control variables.


  1. char c[6];
  2. for (int i = 0; i < 5; i++)
  3. {
  4. cin.get (c[i]);
  5. }
  6. c[5] = 0;

Don't have a compiler handy , but I think this should work. One potential problem is if the user doesn't type in at least 5 characters. That's why getline may be superior here.

http://www.cplusplus.com/reference/i...m/istream/get/

[edit]
Replace "cin" with "input" above. I didn't pay attention to the fact that you had an istream, not necessarily cin.
[/edit]
Last edited by VernonDozier; Nov 5th, 2009 at 6:25 pm. Reason: Assumed cin as the stream earlier.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 17
Reputation: dotnabox is an unknown quantity at this point 
Solved Threads: 0
dotnabox dotnabox is offline Offline
Newbie Poster
 
0
  #5
Nov 5th, 2009
getline() seems to be doing the trick, but for some reason, it will only process once, not twice.

  1. istream &operator>>( istream &input, Time &time)
  2. {
  3. char charHour[60], charMinute[60];
  4. input.getline(charHour, 3, ':');
  5. input.getline(charMinute, 3, ' ');
  6. input.getline(time.period, 3, ' ');
  7. time.hour = atoi(charHour);
  8. time.minute = atoi(charMinute);
  9. }

From my original code, it should run through it once, store it in startTime, then run through it again (when I call the operator once more) and store it in endTime. Instead, it just runs through it for startTime, then leaves, but the data is correctly stored in startTime.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 17
Reputation: dotnabox is an unknown quantity at this point 
Solved Threads: 0
dotnabox dotnabox is offline Offline
Newbie Poster
 
0
  #6
Nov 5th, 2009
So I ended up figuring out how to do it to allow for white space and get the information as needed. Problem is, I cannot seem to store the AM/PM portion.

  1. istream &operator>>( istream &input, Time &time)
  2. {
  3. char s[256];
  4. time.period = new char[3];
  5. input.getline(s, 256);
  6. time.hour = atoi(strtok(s,":"));
  7. time.minute = atoi(strtok(NULL," "));
  8. time.period = strtok(NULL, " ");
  9. }
When I output time.hour and time.minute, they work just fine, but time.period doesn't seem to store anything.

Edit: Take that back. It still has a problem with white space (It's part of the assignment that people can't follow instructions to input a time...) as well.
Last edited by dotnabox; Nov 5th, 2009 at 7:07 pm.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,837
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster
 
0
  #7
Nov 6th, 2009
Without seeing the function calls and the class and the exact assumptions regarding what you can assume as far as data, plus whatever else may be going on with the stream, I'm not 100% sure what the problem is. Note that "time" is highlighted. It's a C++ keyword. I doubt that's the problem, but possibly consider renaming the variable just in case.

I assume this is the criteria, in order:
  1. Any amount of white space.
  2. 0-5 (index 0)
  3. 0-9 (index 1)
  4. : (index 2)
  5. 0-5 (index 3)
  6. 0-9 (index 4)
  7. Exactly one blank space (index 5)
  8. "AM", "PM", "am" or "pm" (indexes 6 and 7)

If this is it, you can use getline to get a maximum of 8 characters, then just go character by character. Use no character delimiter.

  1. // read in and throw away all white-space, character by character, till you get to first non-white space. "Put back" into the stream any non-white-space character if you have read it in.
  2.  
  3. char s[9];
  4. getline (s, 9);
  5. // check length of s using strlen. If it isn't 8, flag as invalid input.
  6.  
  7. // Go through s[] character by character, testing using the criteria above. If any test fails, flag as invalid input.

isspace and isdigit from cctype could come in handy. strlen and strcmp from cstring could also come in handy. peek, get, getline, ignore, unget, and putback from the istream library could be useful.

http://www.cplusplus.com/reference/iostream/istream/

What are you supposed to do if the person enters bad data and what data do you need to be able to handle? Depending on that, you may need to do a variety of things to the stream, including setting or clearing failure bits, or clearing the stream. I'm not trying to over-complicate things, so if I am, I'm sorry. It's just good to know as much as possible what data might be thrown at you, what you need to be able to handle and recover from, and what you don't. If it's simply a cin stream where you ask people to enter times and press enter, then say "Sorry, try again" if it's bad, that's less complicated than if you have to set failure bits at the exact point of failure and allow the stream to be cleared and used again, stuff like that.

This page, as well as the next several pages in the link, might be useful.

http://www.linuxtopia.org/online_boo...mming_074.html
Last edited by VernonDozier; Nov 6th, 2009 at 1:22 am.
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 24
Reputation: boblied is an unknown quantity at this point 
Solved Threads: 9
boblied boblied is offline Offline
Newbie Poster
 
1
  #8
Nov 6th, 2009
Originally Posted by VernonDozier View Post
... Note that "time" is highlighted. It's a C++ keyword.
Sorry for the tangent, but "time" is not a C++ keyword. The fact that it's highlighted is maybe because the syntax highlighter handles multiple languages, and "time" is a keyword in some of them (for instance, in the bash shell); or maybe because there is a Unix/POSIX/C standard function called time() from time.h . But "time" is not a C or C++ keyword, and the global function time() wouldn't conflict with a member variable called "time."
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,837
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster
 
0
  #9
Nov 6th, 2009
Originally Posted by boblied View Post
Sorry for the tangent, but "time" is not a C++ keyword. The fact that it's highlighted is maybe because the syntax highlighter handles multiple languages, and "time" is a keyword in some of them (for instance, in the bash shell); or maybe because there is a Unix/POSIX/C standard function called time() from time.h . But "time" is not a C or C++ keyword, and the global function time() wouldn't conflict with a member variable called "time."
Yes, you are correct. Thanks for pointing that out. I was thinking of the time(time_t*) function. I was pretty sure it would not be a problem, but should not have called it a keyword. Here is a list of keywords.

http://www.cppreference.com/wiki/keywords/start
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC