Mawg
Mawg

Reputation: 40215

Extract string from string containing with date/time

Given the string

[FROM] Jan 5 2013 10:16:41 widget <__FILE__> <__LINE__>

I want to extract the "peripheral", in this case "widget".

The "peripheral" name always starts in the same column - but it can have different lengths, so I suppose I could use memcpy() or strncpy() and use strchr() to get the position of the space. I will accept a code answer that does that and works.

However, it got a bit tricky as it has been a while since I've coded in C, so I've tried:

     char traceDirection[11];
     char month[4];
     char day[3];
     char year[5];
     char hour[3];
     char min[3];
     char sec[3];
     sscanf(line,"%s %s %s %s:%s:%s %s %s",  
                  traceDirection, month, day, year, hour, min, sec, peripheralName);

Everything is fine until hour, min, sec, and I suspect it might be because of the colons in the HH:MM:SS

Can someone give me some code, whether using sscanf() or otherwise, to get the name of the peripheral from such a string (I don't care about any of the rest), given that

Thanks in advance. This is what happens when you jump between languages :-(

Upvotes: 0

Views: 279

Answers (4)

Jim Balter
Jim Balter

Reputation: 16424

If your file is truly guaranteed to have that format, the sscanf approach is overkill given your requirements. You already have the line in line, so you can just do

#define WIDGET_COLUMN 27
...
int widgetStart = line + WIDGET_COLUMN;
int widgetLength = strcspn(line[widgetStart], " ");
char* widget = malloc(widgetLength+1);
if (!widget) { /* handle OOM error */ }
memcpy(widget, widgetStart, widgetLength);
widget[widgetLength] = '\0';

Upvotes: 1

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57690

Use int to read Integers, NOT char.

 int day, year, hour, min, sec;
 sscanf(line,"%s %s %d %d %d:%d:%d %s",  
         traceDirection, month, &day, &year, &hour, &min, &sec, peripheralName);

See Ideone

To read only prefipheralName use this,

sscanf(line,"%*[^:]%*s %s", peripheralName);

Here %*[^:] matches anything before first :. Then %*s matches anything before first space. But none of this scan assign any variable. At last %s just scans normally and assigns it to peripheralName.

Upvotes: 2

Colselaw
Colselaw

Reputation: 1079

In the above example, the %s format specifier eats all non-whitespace characters, so the hour is getting all the HH:MM:SS stuff (overrunning the buffer). To limit those to 2 characters, you can do %2s.

PCRE may be more helpful, as well.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727137

Your format string should be as follows:

"%s %s %s %s %2s:%2s:%2s %s"

You need four %s before the colon-separated block %2s:%2s:%2s for HH:MM:SS, and your code had only three %s in there. Also, the strings for HH, MM, and SS should be limited to 2 characters; otherwise, the entire 10:16:41 gets read into the hour string.

Here is a link to a demo on ideone.

Upvotes: 2

Related Questions