parsing a string

S

Stu

Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Thanks in advance for that respond
 
R

Richard Heathfield

Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Look up strrchr.
 
T

Tom St Denis

Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Thanks in advance for that respond

If the date is always at the end, why not work backwards?

:)

Tom -- ruining the education system for others since 1998.
 
E

Eric Sosman

Richard said:
Stu said:


Look up strrchr.

strrchr() doesn't seem to be the answer here. He doesn't
need to find the rightmost '/', but the antepenultimate '/'.
Finding the rightmost does not seem to further his eventual
goal -- not unless he can modify the string, which he hasn't
told is is permissible.

Personally, I'd do it by scanning for '/' characters and
remembering the three most recently found:

char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p;
for (p = the_string; *p != '\0'; ++p) {
if (*p == '/') {
p1 = p2;
p2 = p3;
p3 = p;
}
}
if (p1 == NULL)
die_horribly();
else {
/* p1 points to the start of "/yyyy/mm/dd" */
}

The one-by-one loop could be replaced with strchr():

char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p = the_string;
while ((p = strchr(p, '/')) != NULL) {
p1 = p2;
p2 = p3;
p3 = p++;
}
if (...)
 
S

Simon Biber

Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Thanks in advance for that respond

I doubt you'll get much more efficient than this.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void get_date(long *year, long *month, long *day, const char *date_path)
{
size_t len = strlen(date_path);
assert(len >= 10 && date_path[len - 6] == '/'
&& date_path[len - 3] == '/');
*year = strtol(date_path + len - 10, 0, 10);
*month = strtol(date_path + len - 5, 0, 10);
*day = strtol(date_path + len - 2, 0, 10);
}

int main(void)
{
long year, month, day;
get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
printf("%04ld/%02ld/%02ld\n", year, month, day);
get_date(&year, &month, &day, "1982/09/06");
printf("%04ld/%02ld/%02ld\n", year, month, day);
return 0;
}
 
S

santosh

Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Thanks in advance for that respond

If date will always be of the form YYYY/MM/DD and you know the length
of the string, do:
char *date = (date_path + date_path_length) - 11;

If you know the string length but the date could be of variable length
then do:
char *date = date_path + date_path_length;
size_t cnt;
for(cnt = 0; date >= date_path || cnt < 3; date--)
if(*date == '/') cnt++;

If string length is unknown then a straightforward scan from the
beginning using isdigit() might be the best option.
 
R

Richard Heathfield

Eric Sosman said:
strrchr() doesn't seem to be the answer here. He doesn't
need to find the rightmost '/', but the antepenultimate '/'.
Finding the rightmost does not seem to further his eventual
goal -- not unless he can modify the string, which he hasn't
told is is permissible.

On reflection, you're right. I suppose I'm so used to thinking of strchr
strchr strchr to find the third foo in the bar, and so used to thinking of
strrchr as the "opposite" of strchr, that this was kind of a mistake
waiting to happen. Still, it would have got him a third the way there!
 
S

Simon Biber

Eric said:
strrchr() doesn't seem to be the answer here. He doesn't
need to find the rightmost '/', but the antepenultimate '/'.
Finding the rightmost does not seem to further his eventual
goal -- not unless he can modify the string, which he hasn't
told is is permissible.

In fact from his code:
char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
; it's pretty clear that it is not permissible to modify the string.

While thinking about a solution I first thought about strrchr, then
realised it didn't help for finding the second-to-last or third-to-last.

But if the format is fixed at YYYY/MM/DD then all you need to do is find
the length of the string and subtract 10 from that.
 
C

CBFalconer

Simon said:
.... snip ...

In fact from his code:
char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
; it's pretty clear that it is not permissible to modify the string.

While thinking about a solution I first thought about strrchr, then
realised it didn't help for finding the second-to-last or third-to-last.

But if the format is fixed at YYYY/MM/DD then all you need to do is
find the length of the string and subtract 10 from that.

It that is really the case he just needs to divide the definition
up into:

char *date_hdr = "/dira/dirb/dirc/dird/";
char *date_id = "2006/12/04";
 
K

Keith Thompson

Simon Biber said:
Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.
char *date_path = "/dira/dirb/dirc/dird/2006/12/04"
Note: the number of directories before the date can vary.
Thanks in advance for that respond

I doubt you'll get much more efficient than this.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void get_date(long *year, long *month, long *day, const char *date_path)
{
size_t len = strlen(date_path);
assert(len >= 10 && date_path[len - 6] == '/'
&& date_path[len - 3] == '/');
*year = strtol(date_path + len - 10, 0, 10);
*month = strtol(date_path + len - 5, 0, 10);
*day = strtol(date_path + len - 2, 0, 10);
}

int main(void)
{
long year, month, day;
get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
printf("%04ld/%02ld/%02ld\n", year, month, day);
get_date(&year, &month, &day, "1982/09/06");
printf("%04ld/%02ld/%02ld\n", year, month, day);
return 0;
}

In real life, of course, you wouldn't want to use assert(). This
code, as written, doesn't give the caller any opportunity to handle
errors.

Probably the best approach is for get_date to return an error indication.
 
J

Joe Wright

Simon said:
Stu said:
Can somebody please tell me the most effient away to parse the date
YYYYMMDD from the following string.

char *date_path = "/dira/dirb/dirc/dird/2006/12/04"

Note: the number of directories before the date can vary.

Thanks in advance for that respond

I doubt you'll get much more efficient than this.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void get_date(long *year, long *month, long *day, const char *date_path)
{
size_t len = strlen(date_path);
assert(len >= 10 && date_path[len - 6] == '/'
&& date_path[len - 3] == '/');
*year = strtol(date_path + len - 10, 0, 10);
*month = strtol(date_path + len - 5, 0, 10);
*day = strtol(date_path + len - 2, 0, 10);
}

int main(void)
{
long year, month, day;
get_date(&year, &month, &day, "/dira/dirb/dirc/dird/2006/12/04");
printf("%04ld/%02ld/%02ld\n", year, month, day);
get_date(&year, &month, &day, "1982/09/06");
printf("%04ld/%02ld/%02ld\n", year, month, day);
return 0;
}
Maybe..

#include <stdio.h>
#include <string.h>

int main(void) {
char *date_path = "/dira/dirb/dirc/dird/2006/12/04";
char *date = date_path + (strlen(date_path) - 10);
puts(date_path);
puts(date);
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top