我正在尝试使用 C
标准库中的 sscanf()
函数从文件中读取特定数字。我的示例数据来自运行 Linux 内核
的系统上的 /proc/stat
。这是它的样子:
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);
}
最佳答案
您不想禁止分配 cpu
之后的数字。但是,您也不想跳过空白,因此您需要使用 %c
或 %[]
因为所有其他格式(除了 %n
,在此上下文中绝对不算数)跳过前导空格。反过来,这意味着您需要读取一个字符串,而不是一个整数。所以,代码应该是:
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…
关于c - 如何使用 sscanf 从相似的行中读取特定数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28518704/