从包含日期/时间的字符串中提取字符串

时间:2013-01-05 04:05:38

标签: c scanf

给出字符串

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

我想提取“外围设备”,在本例中是“小部件”。

“外围”名称始终在同一列中开始 - 但它可以有不同的长度,所以我想我可以使用memcpy()或strncpy()并使用strchr()来获取空间的位置。我将接受这样做的代码答案并且有效。

然而,由于我用C编码已经有一段时间了,它有点棘手,所以我试过了:

     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);

一切都很好,直到小时,分钟,秒,我怀疑它可能是因为HH中的冒号:MM:SS

有人可以给我一些代码,无论是使用sscanf()还是其他方式,从这样的字符串中获取外围设备的名称(我不关心任何其他的),鉴于

  • 这些行总是具有相同的格式
  • 外围设备的名称始终在同一列中开始
  • 然而,它没有固定的长度;它以空格终止

提前致谢。当你在语言之间跳转时会发生这种情况: - (

4 个答案:

答案 0 :(得分:2)

您的格式字符串应如下所示:

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

%s的冒号分隔区块%2s:%2s:%2s之前,您需要四个HH:MM:SS,而您的代码中只有三个%s。此外,HHMMSS的字符串应限制为2个字符;否则,整个10:16:41会被读入hour字符串。

这是link to a demo on ideone

答案 1 :(得分:2)

使用int读取整数,而不是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);

请参阅Ideone

要阅读 only prefipheralName ,请使用此

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

此处%*[^:]匹配首先:之前的所有内容。然后%*s匹配第一个空格之前的任何内容。但是这个扫描都没有分配任何变量。最后%s只是正常扫描并将其分配给peripheralName

答案 2 :(得分:1)

在上面的示例中,%s格式说明符会占用所有非空白字符,因此小时数将获得所有HH:MM:SS内容(超出缓冲区)。要将这些限制为2个字符,您可以执行%2s

PCRE也可能更有帮助。

答案 3 :(得分:1)

如果您的文件确实保证具有该格式,则根据您的要求,sscanf方法过度。您已经在line中拥有该行,因此您可以执行

#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';