C:输出解析两次时如何避免重复popen?
C: how to avoid repeating popen when output parsed twice?
我想解析 popen(3)
的输出,但看起来我必须重复 popen()
调用。
#include <stdio.h>
int main(int argc, char *argv[]) {
int v1, v2, v3;
char unused[255];
FILE *f;
f = popen("ip -V", "r");
fscanf(f, "ip utility, iproute2-v%d.%d.%d-%s", &v1, &v2, &v3, unused);
printf("%d.%d.%d (%s)\n", v1, v2, v3, unused);
f = popen("ip -V", "r"); // TODO: how to avoid repeating popen()?
fscanf(f, "ip utility, iproute2-%d.%d.%d", &v1, &v2, &v3);
printf("%d.%d.%d\n", v1, v2, v3);
pclose(f);
return 0;
}
正在测试此版本:
$ ip -V
ip utility, iproute2-5.8.0
没有重复,它保持旧值:
$ ./fscanf-popen
32764.-1446225616.0 ()
32764.-1446225616.0
通过重复它可以正确处理它:
$ ./fscanf-popen
32765.1933255568.0 ()
5.8.0
fseek(f, 0, SEEK_SET);
和 rewind(f);
没有帮助。
我必须错过一些明显的东西。
您正在使用 fscanf()
解析管道的输出,它会消耗来自流的输入,直到它满足指定的格式。出于这个原因,没有进一步的 fscanf
将只读取流中存在的任何新数据。相反,您需要的是将输入存储到一个字符串(char
s 的数组)中。
为了完成这个任务,您可以使用 fgets()
来阅读整行。通过这种方式,您将始终能够将存储的字符串传递给 sscanf()
,或执行检索字符串包含的值所需的任何其他解析操作:
char buf[1000];
f = popen("ip -V", "r");
if( f )
{
char *ret = fgets(buf, 1000, f);
if( ret )
{
sscanf(buf, "ip utility, iproute2-v%d.%d.%d-%s", &v1, &v2, &v3, unused); // or any other proper parsing action
printf("%d.%d.%d (%s)\n", v1, v2, v3, unused);
}
/* ... */
pclose(f);
}
fgets
只读取一行(保留尾随换行符)。如果您需要阅读 N 行,只需迭代重复它直到 returns NULL
.
我想解析 popen(3)
的输出,但看起来我必须重复 popen()
调用。
#include <stdio.h>
int main(int argc, char *argv[]) {
int v1, v2, v3;
char unused[255];
FILE *f;
f = popen("ip -V", "r");
fscanf(f, "ip utility, iproute2-v%d.%d.%d-%s", &v1, &v2, &v3, unused);
printf("%d.%d.%d (%s)\n", v1, v2, v3, unused);
f = popen("ip -V", "r"); // TODO: how to avoid repeating popen()?
fscanf(f, "ip utility, iproute2-%d.%d.%d", &v1, &v2, &v3);
printf("%d.%d.%d\n", v1, v2, v3);
pclose(f);
return 0;
}
正在测试此版本:
$ ip -V
ip utility, iproute2-5.8.0
没有重复,它保持旧值:
$ ./fscanf-popen
32764.-1446225616.0 ()
32764.-1446225616.0
通过重复它可以正确处理它:
$ ./fscanf-popen
32765.1933255568.0 ()
5.8.0
fseek(f, 0, SEEK_SET);
和 rewind(f);
没有帮助。
我必须错过一些明显的东西。
您正在使用 fscanf()
解析管道的输出,它会消耗来自流的输入,直到它满足指定的格式。出于这个原因,没有进一步的 fscanf
将只读取流中存在的任何新数据。相反,您需要的是将输入存储到一个字符串(char
s 的数组)中。
为了完成这个任务,您可以使用 fgets()
来阅读整行。通过这种方式,您将始终能够将存储的字符串传递给 sscanf()
,或执行检索字符串包含的值所需的任何其他解析操作:
char buf[1000];
f = popen("ip -V", "r");
if( f )
{
char *ret = fgets(buf, 1000, f);
if( ret )
{
sscanf(buf, "ip utility, iproute2-v%d.%d.%d-%s", &v1, &v2, &v3, unused); // or any other proper parsing action
printf("%d.%d.%d (%s)\n", v1, v2, v3, unused);
}
/* ... */
pclose(f);
}
fgets
只读取一行(保留尾随换行符)。如果您需要阅读 N 行,只需迭代重复它直到 returns NULL
.