LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-29-2005, 03:31 PM   #1
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Rep: Reputation: 30
c++ parse date string??


Hey all, having a little trouble parsing a char string in format (MM/DD/YYYY)

I want to separate the month, day, and year into 3 char arrays.

here is waht i have. If anyone has a better implementation, would be much appretiated!!

Code:
char itemDate[11];
            for (int i = 0; i <= lastSold; i++)
            {
                strcpy(itemDate, OS->OSgetFinalSale(i));
                //itemDate = OS->OSgetFinalSale(i); // return size is 80
                cout << itemDate << endl;

            char Imonth[3], Iday[3], Iyear[5];
            int i;
            for (i = 0; i < 2; i++)
            {
                Imonth[i]=itemDate[i];
            }
            for (i = 3; i < 5; i++)
            {
                Iday[i-3]=itemDate[i];
            }
            for (i = 6; i<10; i++)
            {
                Iyear[i-6]=itemDate[i];
            }

            cout << "Imonth: " << Imonth << endl;
            cout << "Iday: " << Iday << endl;
            cout << "Iyear: " << Iyear << endl << endl;
             }
the strcpy, OS->OSgetFinalSale returns a char in format (MM/DD/YYYY) this is the char to parse.

my output is very wierd, here it is:

Code:
Imonth:
Iday: ��
Iyear:�����

12/12/2004
Imonth: 12%
Iday: 12��
Iyear: 200�����

12/12/2004
Imonth: 12%
Iday: 12��
Iyear: 200�����

12/12/2004
Imonth: 12%
Iday: 12��
Iyear: 200�����

12/14/2004
Imonth: 12%
Iday: 14��
Iyear: 200�����
any ideas what i am doing wrong?? I have had this proble before, but the strcpy usually solved the issue.
Thanks so much,
Josh
 
Old 08-29-2005, 04:12 PM   #2
spooon
Senior Member
 
Registered: Aug 2005
Posts: 1,755

Rep: Reputation: 51
C-style strings must be terminated with null (i.e. '\0').

Last edited by spooon; 08-29-2005 at 04:15 PM.
 
Old 08-29-2005, 04:25 PM   #3
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
yes i am aware of that fact.
Thats why i left an extra cell for the null terminating char '\0' but that does not help me out.

thank you though
 
Old 08-29-2005, 04:27 PM   #4
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
I fail to see where you NULL terminate your strings... You leave space for them, but never set that space to NULL.

Perhaps you are also aware that when you have uninitialized, non-global variables like that they will be filled with garbage until you set them...
 
Old 08-30-2005, 11:59 AM   #5
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
oohhh ok, i understand what you are saying,
So i should set each char to:

Code:
char Imonth[3] = "";
????

and you are saying i need to explicity terminiate the strings? how would i go about doin this? , or just append \0 to the end??

thanks so much
 
Old 08-30-2005, 12:26 PM   #6
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
You can make sure it is null terminated by doing any of the following types of things:

Code:
Imonth[2] = '\0';
Imonth[2] = NULL;

memset(Imonth, 0, 3);
// the ANSI-C string functions NULL terminate for you so the
// following should even work.
strncpy(Imonth, itemDate, 2);
In this case, initializing the strings to "" probably isn't necessary since you set them right away. (Though, it still is good practice to initialize variables.)

I don't think initializing them to "" alone would help in this case. It would still likely leave garbage in the last array positions.
 
Old 08-30-2005, 01:17 PM   #7
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
hmmm, my compiler did not like
null or '\0'....

and with the strncpy, my issue is that i need to parse out certain char cells in the original array,
i need to go from MM/DD/YYYY
to array1 = MM
array2=DD
array3=YYYY

the strncpy, will only copy the FIRST n chars. and the way i have structured this with the for statemetns and a simply assignment, does not copy the chars correctly...
thanks for the help!

Josh
 
Old 08-30-2005, 02:15 PM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941
Take a look at man regex. A regular expression is a "pattern" that can be applied to a string, such as a date, and the regular-expression engine will isolate the substrings that match the pattern.
 
Old 08-30-2005, 03:13 PM   #9
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
strncpy(Imonth, itemDate, 2);
strncpy(Iday, &itemDate[3], 2);
strncpy(Iyear, &itemDate[6], 4);

It should be NULL, not null. I believe NULL is defined in one of the standard headers so as long as you include something like iostream it should be there.

Not quite sure why you would get compiler errors with '\0'. Posts some of the exact errors you get.

Using a regular expression is probably a safer method. Better yet would be some sort of internationalized date/time library that can parse a date in a number of formats and give you back the month/day/year. I haven't had to do much with manipulating date/times in C/C++ though, so I can't recommend any off the top of my head.

However, if you know that you will always get a date back in that specific format, your methods should be ok.

Last edited by deiussum; 08-30-2005 at 03:17 PM.
 
Old 08-30-2005, 03:38 PM   #10
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
hmmm interesting methods, yes that did work, however still the funny characters, when i assign each char to NULL the error is
an invalid initalizer. My headers are included correctly, i know that.

Something i saw, that looked like it would work is this:
Code:
string s1 = "hello world";
	string s2(s1, 6, 5);		// s2 is "world"
which supposidly slices a string. however i would need to cast my char to a string?
is this better, or your method?

And qeustion in your method, why in the first reference to itemDate, we dont need an & but the second and third we do?

Thanks for all the help!
Josh
 
Old 08-30-2005, 03:50 PM   #11
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Yeah, you could use a std::string as well. The std::string also has a substring method, so you could put the whole date into a std::string, then use substr to break it up. For example:

Code:
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string sDate = "12/20/2004";
    string sMonth = sDate.substr(0, 2);
    string sDay = sDate.substr(3, 2);
    string sYear = sDate.substr(6, 4);

    cout << "Month: " << sMonth << endl
        << "Day: " << sDay << endl
        << "Year: " << sYear << endl;

    return 0;
}
Note: You could also do something like the above with a stringstream too and easily get the date/month/year as integers if that's the form you ultimately want them in. For instance:

Code:
#include <iostream>
#include <sstream>

using namespace std;

int main()
{
    stringstream ss;
    int nMonth;
    int nDay;
    int nYear;

    ss << "12/20/2005";

    ss >> nMonth;
    ss.ignore(1); // ignore the '/' character
    ss >> nDay;
    ss.ignore(1);  // ignore the '/' character
    ss >> nYear;

    cout << "Month: " << nMonth << endl
        << "Day: " << nDay << endl
        << "Year: " << nYear << endl;

    return 0;
}
In the example in my previous post, the reference isn't needed because itemDate is essentially the same as &itemDate[0]. When using a pointer to an array like that, it is essentially a pointer to the first element of the array. In the other 2 cases, you are getting a pointer to a character later on in the array.

In other words:
  • itemDate is basically a char* pointing to element 0.
  • itemDate[3] is a char at array element 3.
  • &itemDate[3] is basically a char* pointing to element 3.

It's a handy little trick, but a bit dangerous if itemArray doesn't actually have that number of elements since you could go beyond the bounds of the array.

When you got the errors, were you trying to initialize your arrays like so?:

char Imonth[3] = '\0'; // or NULL

Because that wouldn't work. You need to set the specific character at the end to '\0' or NULL, most likely after you had already filled in the other characters. For instance, taking your code above:

Code:
for (i = 0; i < 2; i++)
{
    Imonth[i]=itemDate[i];
}
Imonth[2] = '\0'; // or NULL

Last edited by deiussum; 08-30-2005 at 03:59 PM.
 
Old 08-30-2005, 04:19 PM   #12
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
freaking genious, haha, thanks so much,
used the string idea.

Code:
string Idate;

        strcpy(itemDate, OS->OSgetFinalSale(i));
        cout <<"ItemDate: " << itemDate << endl;

        Idate.assign(itemDate);
        cout << "string: " << Idate << endl;
        string Imonth = Idate.substr(0,2);
        string Iday = Idate.substr(3,2);
        string Iyear = Idate.substr(6,4);
worked like a champ.

And when i was assigning the char, i tried both NULL and '\0', both threw up with invalid initializer. very wierd huh

now i just need to convert this STRING into an int.
thanks for all the help so much!

Josh
 
Old 08-30-2005, 04:28 PM   #13
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
HAHAHA my bad, i love how i read things half way, get excited and forget about the rest, yep the rest of your post surley tells me how to get them as an int


but how does the stringstream know to read on 2 string chars for the first int, ignore the '/' , read the next 2 string chars, ignore the '/'????
thanks again
 
Old 08-30-2005, 05:01 PM   #14
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Glad it helped.

When streaming to an int, it will read until it finds a non-numeric character. And then I used the ignore method to ignore the / and streamed to another int...

And invalid initializer seems to indicate to me that you were using '\0' and NULL as the initializer when declaring the array, not just setting a single character of the array (which is usually an invalid conversion error when trying to convert the wrong type to a char).

Oh well... as long as you got something working.

Last edited by deiussum; 08-30-2005 at 05:08 PM.
 
Old 08-31-2005, 12:51 PM   #15
blizunt7
Member
 
Registered: Mar 2004
Distribution: Fedora Core 1,2,3, RHEL3,4,5 Ubuntu
Posts: 274

Original Poster
Rep: Reputation: 30
ok, great, im almost on my way.

however the stringstream, does not conserve a zero????

if my string was 04/12/2004

and i print out, the month would be 4, not 04, i need the 04??

any ideas?
thanks again so much, been great help
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Parse String in a Bash script jimwelc Linux - Newbie 8 11-09-2012 07:47 AM
Parse --static string no delimiters DaFrEQ Programming 2 04-08-2005 02:06 PM
Parse RPM version string in Bash jimwelc Linux - Newbie 1 02-28-2005 05:22 PM
Parse a perl string djgerbavore Programming 3 10-31-2004 07:23 AM
C++ and C# Parse a string into a numerical type exodist Programming 8 02-23-2004 06:15 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:00 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration