shaolinfunk
asked on
How do I parse this string for the year, month, and day?
Ok, I have today's date in a character array.
How do I parse it so that I can store the year, month, and day into variables "year", "month", and "day".
My code is attached. Yes, I am learning. Yes, I am only on Chapter 4 in my teach-yourself, self-help book. And yes, I am not a computer programmer. Thank you in advance for your help!
How do I parse it so that I can store the year, month, and day into variables "year", "month", and "day".
My code is attached. Yes, I am learning. Yes, I am only on Chapter 4 in my teach-yourself, self-help book. And yes, I am not a computer programmer. Thank you in advance for your help!
int main()
{
// Get TODAY's date in string form
time_t rawtime;
struct tm * timeinfo;
char str[60];
time ( &rawtime );
timeinfo = localtime ( &rawtime );
strftime(str, sizeof(str) , "%d%b%Y", timeinfo);
// printf(str); //lets me see if date is right
// Get YESTERDAY's date
unsigned short year;
unsigned short month;
unsigned short day;
year = 2010;
month = 3;
day = 31;
one_Day_Earlier(year, month, day);
return 0;
}
>> I have today's date in a character array.
In your OP you have three representations of today's date:
12: char array
9: seconds since epoch
10: timeinfo, a pointer to struct tm whose values are filled in with your local time.
In your OP you have three representations of today's date:
12: char array
9: seconds since epoch
10: timeinfo, a pointer to struct tm whose values are filled in with your local time.
ASKER
well I don't really understand or want to understand 9 or 10 yet (pointers?).
12, a char array, is something i've covered in my book. how do i extract from that char array the values needed for the unsigned shorts i've declared?
12, a char array, is something i've covered in my book. how do i extract from that char array the values needed for the unsigned shorts i've declared?
The easiest way to store into variable year, month, day is to use the timeinfo pointer.
Here is what a struct tm looks like:
http://www.cplusplus.com/reference/clibrary/ctime/tm/
Note in particular the unusual ranges for month and year!
Here is what a struct tm looks like:
http://www.cplusplus.com/reference/clibrary/ctime/tm/
Note in particular the unusual ranges for month and year!
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday; // you need this for the day of the month
int tm_mon; // you need this for the month
int tm_year; // you need this for the year
int tm_wday;
int tm_yday;
int tm_isdst;
OK, scratch the struct tm details and the reference to pointers. You want the Month to be digits, right? So, modify the strftime as shown below to get a month number rather than, say, Apr. If you prefer, you can keep the Apr in the string, and then you can convert the month name into a number.
The whitespace between the fields will be used to separate the three strings when converting to a number.
Which way do you want to go: "Apr" or "04". The leading 0 is part of the strftime result; but that will not be a problem if you want the integer number 4.
The whitespace between the fields will be used to separate the three strings when converting to a number.
Which way do you want to go: "Apr" or "04". The leading 0 is part of the strftime result; but that will not be a problem if you want the integer number 4.
strftime(str, sizeof(str), "%Y %m %d", timeinfo);
Your layout of str is "YYYY MM DD"
To convert an ASCII representation of a number to an integer, you can use atoi.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
But that requires a just a little bit of pointers. To get the year, it is as simple as saying
year = atoi(str).
since str, an array name, is actually a constant pointer to the starting address of the array.
(BTW, I am not at a computer, so be sure to check code on your system.)
If you want to avoid atoi because it has a pointer in it, then you have to parse each field in str yourself and compute the integer.
For example, 2010: 0+1*10+0*100+2*1000
To convert an ASCII representation of a number to an integer, you can use atoi.
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
But that requires a just a little bit of pointers. To get the year, it is as simple as saying
year = atoi(str).
since str, an array name, is actually a constant pointer to the starting address of the array.
(BTW, I am not at a computer, so be sure to check code on your system.)
If you want to avoid atoi because it has a pointer in it, then you have to parse each field in str yourself and compute the integer.
For example, 2010: 0+1*10+0*100+2*1000
Or, I can come up with C++ approach, but that would not be covered in Chapters 1-4 I don't think. What do you know about streams?
To convert a single char that has an ASCII digit in it, you can use something like this:
char digit = '5'; // this is just setup code
int intDigit = digit - '0'; // this is how to convert a single char digit into an integer digit
Now, if you care about robustness, you might want to test to make sure that there really is an ASCII digit present. For that you can use isdigit.
http://www.cplusplus.com/reference/clibrary/cctype/isdigit/
char digit = '5'; // this is just setup code
int intDigit = digit - '0'; // this is how to convert a single char digit into an integer digit
Now, if you care about robustness, you might want to test to make sure that there really is an ASCII digit present. For that you can use isdigit.
http://www.cplusplus.com/reference/clibrary/cctype/isdigit/
ASKER
Hi Phoffric,
I want to continue this thread but got stuck because my program no longer compiles after I implemented the code from your previous thread...
https://www.experts-exchange.com/questions/25651416/How-do-I-count-backwards-in-days-on-the-calendar.html
Once I get past whatever error is being generated, I can compile and move forward with this thread...
I want to continue this thread but got stuck because my program no longer compiles after I implemented the code from your previous thread...
https://www.experts-exchange.com/questions/25651416/How-do-I-count-backwards-in-days-on-the-calendar.html
Once I get past whatever error is being generated, I can compile and move forward with this thread...
I can now get onto a machine with a compiler. Be back soon.
OK, I have a computer now. The
using namespace std;
statement should have fixed your compilation errors, right?
using namespace std;
statement should have fixed your compilation errors, right?
ASKER
ah yes, that was it. however, i do get some warnings regarding that 'sprintf' stuff you suggested. what does it mean to be "declared deprecated"?
1>------ Build started: Project: junk, Configuration: Debug Win32 ------
1>Compiling...
1>Junk.cpp
1>c:\documents and settings\administrator\desktop\junk\junk\junk.cpp(41) : warning C4996: 'sprintf' was declared deprecated
1> c:\program files (x86)\microsoft visual studio 8\vc\include\stdio.h(345) : see declaration of 'sprintf'
1> Message: 'This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
1>c:\documents and settings\administrator\desktop\junk\junk\junk.cpp(56) : warning C4996: 'localtime' was declared deprecated
1> c:\program files (x86)\microsoft visual studio 8\vc\include\time.inl(114) : see declaration of 'localtime'
1> Message: 'This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
1>Linking...
1>Embedding manifest...
1>Build log was saved at "file://c:\Documents and Settings\Administrator\Desktop\junk\junk\Debug\BuildLog.htm"
1>junk - 0 error(s), 2 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
ASKER
fyi, this is how my code looks when it generated those errors:
#include <time.h>
#include <stdio.h>
#include <string>
using namespace std;
string one_Day_Earlier(unsigned short year, unsigned short month, unsigned short day)
{
//months with 31 days: 1, 3, 5, 7, 8, 10, 12
//months with 30 days: 4, 6, 9, 11
//months with 28/29 days: 2
day = day - 1; //decrement the day
if (day == 0) //if day = 0, today must be 1st of the month
{
if (month == 2 || month == 4 || month == 6 || month == 8 || month == 9 || month == 11 || month == 1)
{
day = 31;
}
if (month == 5 || month == 7 || month == 10 || month == 12)
{
day = 30;
}
if (month == 3) //if not a leap year, who cares, just search, find nothing, skip, and decrement to 28
{
day = 29;
}
month = month - 1;
if (month == 0) //if this month is Jan, prior month will be Dec.
{
month = 12; //if we are in Dec., we must be in prior year...so...
year = year - 1; //we will never count back before year 2000, so it's always positive
}
}
char buffer[40];
sprintf( buffer, "%d\\\\%d\\\\%d", year, month, day);
return string(buffer);
}
int main()
{
// Get TODAY's date in string form
time_t rawtime; //rawtime is variable of data type time_t, related to time.h
struct tm * timeinfo; //timeinfo points to a struct of type tm, related to time.h
char str[60];
rawtime = time (NULL); //retrieves number of seconds from 1/1/70, in GMT, stores in address of rawtime
timeinfo = localtime ( &rawtime ); //localtime takes rawtime, and creates a "tm" struct
strftime(str, sizeof(str) , "%Y %m %d", timeinfo);
printf(str); //lets me see if date is right
// Get YESTERDAY's date
unsigned short year;
unsigned short month;
unsigned short day;
year = 2010;
month = 3;
day = 31;
// newdate = one_Day_Earlier(year, month, day);
return 0;
}
Deprecated means that someday this function won't be supported; so they recommend that you stop using it. Sometimes the "unsafe" conditions pertains to multi-threading, which you currently are not involved with. The time.h header is pretty bad w.r.t. multi-threading. I had to use time.h and had to use semaphores to protect against threads clobbering each other w.r.t. time.
Search your other threads for how to put _CRT_SECURE_NO_DEPRECATE in your project to remove these warnings. I recall including directions in one of them.
Search your other threads for how to put _CRT_SECURE_NO_DEPRECATE in your project to remove these warnings. I recall including directions in one of them.
ASKER
i like using atoi...it's simple...and i get it. but using atoi(str) only gives us the year...how do i get the month and day as well?
ASKER
yes, you did in fact tell me how to get rid of them...i am just leaving them in for now so that i can get a sense of what kind of warnings will be generated with the code.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ohhhh, now i get it! thanks! this process is really helping me. EE is awesome. what a great learning tool.
ASKER
Ok here's my final code. My gut tells me I should call a function from main that is called GetTodaysDate. It would just look prettier and be easier to read.
However, I don't know how I should be passing-by-value correctly.
I get some warnings when compiling this. What am I doing wrong?
However, I don't know how I should be passing-by-value correctly.
I get some warnings when compiling this. What am I doing wrong?
#include <time.h>
#include <stdio.h>
#include <string>
using namespace std;
unsigned short GetTodaysDate(unsigned short year, unsigned short month, unsigned short day)
{
time_t rawtime; //rawtime is variable of data type time_t, related to time.h
struct tm * timeinfo; //timeinfo points to a struct of type tm, related to time.h
char str[60];
rawtime = time (NULL); //retrieves number of seconds from 1/1/70, in GMT, stores in address of rawtime
timeinfo = localtime ( &rawtime ); //localtime takes rawtime, and creates a "tm" struct
strftime(str, sizeof(str) , "%Y %m %d", timeinfo);
// printf(str); //lets me see if date is right
year = atoi(&str[0]);
month = atoi(&str[5]);
day = atoi(&str[8]);
return (year, month, day);
}
string one_Day_Earlier(unsigned short year, unsigned short month, unsigned short day)
{
//months with 31 days: 1, 3, 5, 7, 8, 10, 12
//months with 30 days: 4, 6, 9, 11
//months with 28/29 days: 2
day = day - 1; //decrement the day
if (day == 0) //if day = 0, today must be 1st of the month
{
if (month == 2 || month == 4 || month == 6 || month == 8 || month == 9 || month == 11 || month == 1)
{
day = 31;
}
if (month == 5 || month == 7 || month == 10 || month == 12)
{
day = 30;
}
if (month == 3) //if not a leap year, who cares, just search, find nothing, skip, and decrement to 28
{
day = 29;
}
month = month - 1;
if (month == 0) //if this month is Jan, prior month will be Dec.
{
month = 12; //if we are in Dec., we must be in prior year...so...
year = year - 1; //we will never count back before year 2000, so it's always positive
}
}
char buffer[40];
sprintf( buffer, "%d\\\\%d\\\\%d", year, month, day);
return string(buffer);
}
int main()
{
// Get TODAY's date in string form
unsigned short year;
unsigned short month;
unsigned short day;
GetTodaysDate (year, month, day);
// Get YESTERDAY's date
// newdate = one_Day_Earlier(year, month, day);
return 0;
}
1>Junk.cpp
1>c:\documents and settings\administrator\desktop\junk\junk\junk.cpp(74) : warning C4700: uninitialized local variable 'day' used
1>c:\documents and settings\administrator\desktop\junk\junk\junk.cpp(74) : warning C4700: uninitialized local variable 'month' used
1>c:\documents and settings\administrator\desktop\junk\junk\junk.cpp(74) : warning C4700: uninitialized local variable 'year' used
1>Linking...
1>Embedding manifest...
1>Build log was saved at "file://c:\Documents and Settings\Administrator\Desktop\junk\junk\Debug\BuildLog.htm"
1>junk - 0 error(s), 3 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
So, now you're a pointer Expert. Start helping others in the C or C++ zone. You help; and you will learn better.
I'll be back tonight. But if you want to start the integration phase, go right ahead. You may get fresh ideas that are simpler than what we have already done. At this point, be flexible in changing the profile of the function(s) you have. The main problem you face w/o using struct or pointer or reference is how to return multiple items from one function. I think you need to re-read chapter 4.
The shortcut easiest way, I think may be for you to use references. But now the the & has a different meaning. Since I'm leaving now, I suggest that you ask a related question from this question, and learn how to return multiple items.
I see that you just posted a new function. Good, go with your gut. One thing that may help the Expert is for you to add a function comment that explains what the input and output is. Good luck!
I'll be back tonight. But if you want to start the integration phase, go right ahead. You may get fresh ideas that are simpler than what we have already done. At this point, be flexible in changing the profile of the function(s) you have. The main problem you face w/o using struct or pointer or reference is how to return multiple items from one function. I think you need to re-read chapter 4.
The shortcut easiest way, I think may be for you to use references. But now the the & has a different meaning. Since I'm leaving now, I suggest that you ask a related question from this question, and learn how to return multiple items.
I see that you just posted a new function. Good, go with your gut. One thing that may help the Expert is for you to add a function comment that explains what the input and output is. Good luck!
ASKER
Ok, catch up with you later tonight hopefully. I can't stop until I finish this thing! It's becoming all-consuming.
ASKER
So that year = 2010, month = 4, and day = 2. How do I do this?