0

给定字符串

[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

4 回答 4

2

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

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

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

这是ideone 上演示的链接

于 2013-01-05T04:11:54.320 回答
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

要只读prefipheralName使用这个,

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

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

于 2013-01-05T04:27:01.297 回答
1

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

PCRE 也可能更有帮助。

于 2013-01-05T04:18:31.387 回答
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';
于 2013-01-05T05:08:20.163 回答