
|
View Full Version : Trying to read in C++ string as MM/DD/YYYY and output as Month DD, YYYY
Liguidsoul 03-03-2005, 06:33 PM I'm doing something wrong with the cin.getline()'s which is causing it to read in incorrect inputs. What is the problem?
I know the outputs are incorrect, those are just temporary so I can check the output. Once the output looks right I'll get it to output the date as the new format:
#include <iostream>
#include <cstring>
using namespace std;
int main ()
{
char month[3];
char day[3];
char year[5];
cout << "Enter a date in the format of 07/19/2002: ";
cin.getline (month, 3);
cin.ignore ();
cin.getline (day, 3);
cin.ignore ();
cin.getline (year, 5);
cout << "\nYou entered" << endl;
cout << month[0] << month[1] << month[2] << endl;
cout << day[0] << day[1] << day[2] << endl;
cout << year[0] << year[1] << year[2] << endl;
return 0;
}
When I enter 07/19/2002 on the keyboard, the output looks something like this:
You entered
07
(weird characters here)
Liguidsoul 03-03-2005, 06:36 PM Note: I know the strings need to have a null character or something at the end, so that's why I was trying to make the month, day, and year one size larger than they actually are.
Uptime 03-03-2005, 07:15 PM Originally posted by azo313
I'm doing something wrong with the cin.getline()'s which is causing it to read in incorrect inputs. What is the problem?
cin.getline() will read to the end of the line by default. You may specify a "stop" character (ie, '/') as the third argument.
Consider this alternate approach: read the entire line with a single call to cin.getline(), then parse the string.
Liguidsoul 03-03-2005, 08:36 PM Good idea, I'll try your second suggestion and let you know how it goes.
krumms 03-03-2005, 10:52 PM Probably unrelated to your problem, but try using the following instead - I never knew this was possible until recently, but you can actually read from an istream directly into a string!
#include <string>
#include <iostream>
#include <algorithm>
std::string s;
std::getline (cin, s);
Liguidsoul 03-04-2005, 01:26 AM Ok, here's what I tried doing. The problem is that when I input a date in the specified format, the output is the whole thing minus the last character (basically the last number of the year). Why isn't the output the whole thing I entered?
I tried changing the SIZE to 12. I also tried removing the cin.ignore();
Please advise:
#include <iostream>
#include <cstring>
using namespace std;
const int SIZE = 11;
int main ()
{
char original[SIZE];
cout << "Enter a date (in the format of 07/19/2002): ";
cin.getline (original, '\n');
cin.ignore ();
cout << "\nYou entered ";
for (int count = 0; count < SIZE; count++)
cout << original[count];
return 0;
}
Uptime 03-04-2005, 02:01 AM Originally posted by azo313
cin.getline (original, '\n');
cin.ignore ();
would make more sense if replaced by
cin.getline (original, SIZE);
error404 03-04-2005, 03:15 AM If you're going to use C++ I/O, you should use STL containers. It only makes sense. One of the big deals about C++ is that you get STL and OO, which basically frees you from manual memory managment and boundary checking when done properly. Try this instead:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
struct date {
unsigned int year, month, day;
};
date parse_date(const string &s);
int main ()
{
string original;
cout << "Enter a date (in the format of 07/19/2002): ";
getline(cin, original);
cout << "\nYou entered ";
cout << original << endl;
date d = parse_date(original);
cout << "Year: " << d.year << " Month: " << d.month << " Day: " << d.day << endl;
return EXIT_SUCCESS; // a bit pragmatic, but more clear
}
// Just for fun. Untested:
date parse_date(const string &s)
{
// let's just be lame and parse based on character position
// this could be much cleaner by finding the delimiters, but
// stl doesn't provide a handy split and i'm lazy
date d;
d.month = atoi(s.substr(0, 2).c_str());
d.day = atoi(s.substr(3, 2).c_str());
d.year = atoi(s.substr(6, 4).c_str());
return d;
}
Liguidsoul 03-04-2005, 03:27 AM I did it this way, is it ok? Works great.
#include <iostream>
#include <cstring>
using namespace std;
void readDate (char arr[]);
void convertDate (char arr[]);
const int SIZE = 11;
int main ()
{
char original[SIZE];
readDate(original); // call readDate
convertDate(original); // call convertDate
return 0;
}
// Precondition: a character array must be passed to function for arr[]
void readDate (/* inout */ char arr[])
{
cout << "Enter a date (in the format of 07/19/2002): ";
cin.getline (arr, SIZE); // read SIZE characters into the character array
}
// Postcondition: input stream must have been read into character array one character at a time
// Precondition: a character array containing data must be passed to function for arr[]
void convertDate (/* inout */ char arr[])
{
cout << "Date in converted format is: ";
if (arr[0] == '0' && arr[1] == '1') // output written month according to numeric month
cout << "January";
else if (arr[0] == '0' && arr[1] == '2')
cout << "February";
else if (arr[0] == '0' && arr[1] == '3')
cout << "March";
else if (arr[0] == '0' && arr[1] == '4')
cout << "April";
else if (arr[0] == '0' && arr[1] == '5')
cout << "May";
else if (arr[0] == '0' && arr[1] == '6')
cout << "June";
else if (arr[0] == '0' && arr[1] == '7')
cout << "July";
else if (arr[0] == '0' && arr[1] == '8')
cout << "August";
else if (arr[0] == '0' && arr[1] == '9')
cout << "September";
else if (arr[0] == '1' && arr[1] == '0')
cout << "October";
else if (arr[0] == '1' && arr[1] == '1')
cout << "November";
else if (arr[0] == '1' && arr[1] == '2')
cout << "December";
cout << " " << arr[3] << arr[4] << ", " << arr[6] << arr[7] << arr[8] << arr[9] << endl; // output remaining portion of converted date
}
// Postcondition: Converted date printed to screen
error404 03-04-2005, 03:36 AM Well your way will certainly work, it's just a bit cumbersome, especially regarding how it handles outputting the month names. Generally when you're writing functions like string parsing functions, you want to get the data out to do some sort of processing on it later, not just display it. What I'd do (and did) is read the string into 3 integers, which you then return to the calling function. If you wanted to, you could have a third function that converts those three integers into a string of a specific format using a simple lookup table for the date names.
The code you've written will do what you want given perfect input, but it's really not all that useful. I'd suggest trying to write flexible, extensible code whenever you can.
|