如何使用sscanf从类似的行中读取特定数字?

时间:2015-02-14 18:18:20

标签: c scanf

我试图从sscanf()标准库中C函数的文件中读取特定数字。我的示例数据来自运行/proc/stat的系统上的Linux Kernel。以下是它的外观:

cpu  90158 11772 50095 6885572 36975 0 207 0 0 0
cpu0 22942 2975 12847 1720241 9655 0 58 0 0 0
cpu1 23879 2979 12080 1717405 12483 0 45 0 0 0
cpu2 21510 3105 12864 1722238 7790 0 57 0 0 0
cpu3 21824 2712 12301 1725687 7044 0 45 0 0 0
.
.
.
intr 2108705 19 28724 0 0 0 0 0 0 1 90871 0 0 204911 0 0 0 143 0 0 0 0 35 0     0 0 0 2362 0 101810 25 388 0 404786 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 11136028
btime 1423918994
processes 155184
procs_running 2
procs_blocked 1
softirq 2109698 8 644880 168 19330 95660 0 24557 551780 3897 769418

我尝试在if - 语句之后打印所有行,除了那些包含cpu的行直接跟随(没有空格)的数字。这是第一行cpu应与所有其他行一起打印,但例如不是第二行cpu0。此外,这些行中cpu后面的数字应作为int存储到int cpu中。

我真的试图解决这个问题,我至少可以通过使用字符类来获得正确的打印行。我的if - 语句包含:

sscanf(line, "cpu%*1[^ ]%d", &cpu) != 1)

其中%1[^ ]表示在行中读取,直到遇到单个空格(可能不需要1),然后在%d中存储以下数字int cpu。但是为cpuN - 行存储了错误的值。而不是存储0, 1, 2, 3,而是存储值22942, 23879, 21510, 21824。现在这可以追溯到我对%1[^ ]的使用。但我尝试了很多不同的东西,我可能会忽略这一点。除了cpu所遵循的行(没有空格)之外,我如何打印除N之后的N并将int cpu存储在regex.h中的所有行? (如果可能的话,我想避免使用#include <stdio.h> #include <stdlib.h> main(void) { FILE * fp; char * line = NULL; size_t len = 0; ssize_t read; fp = fopen("/proc/stat", "r"); if (fp == NULL) exit(EXIT_FAILURE); while ((read = getline(&line, &len, fp)) != -1) { int cpu; if (sscanf(line, "cpu%*1[^ ]%d", &cpu) != 1) { printf("%s", line); } } fclose(fp); if (line) free(line); exit(EXIT_SUCCESS); } 。)到目前为止,这是我的代码:

{{1}}

2 个答案:

答案 0 :(得分:2)

您不希望在cpu之后取消数字的分配。但是,您也不想跳过空白,因此您需要使用%c%[],因为所有其他格式(%n除外),这绝对不会计入此内容contex)跳过领先的空白。反过来,这意味着您需要读取字符串,而不是整数。所以,代码应该是:

char cpu_str[8];  // Allow for big machines!
if (sscanf(line, "cpu%7[^ ]", cpu_str) != 1)
    printf("%s", line);
else if (sscanf(cpu_str, "%d", &cpu) != 1)
    …oops: may the scanset should be %7[0-9]…
else
    …cpu contains the cpu number…

答案 1 :(得分:0)

建议:

1)将行读入缓冲区

2)strncmp(buffer,&#34; cpu&#34;)if 0,ignore line // notice trailing space

3)strncmp(buffer,&#34; cpu&#34;)if 0,saved = atoi(buffer [3])//没有尾随空格

4)忽略所有其他行