您可以使用libzlib直接打开gzip压缩文件.
它还提供了一个"gzopen"函数,其行为类似于fopen,但对gzip文件进行操作.但是,fscanf可能无法在这样的句柄上工作,因为它需要正常的FILE指针.
如果popen
是公平的游戏,你可以做到这一点fopen
和fscanf
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
const char prefix[] = "zcat ";
const char *arg;
char *cmd;
FILE *in;
char buf[4096];
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 1;
}
arg = argv[1];
cmd = malloc(sizeof(prefix) + strlen(arg) + 1);
if (!cmd) {
fprintf(stderr, "%s: malloc: %s\n", argv[0], strerror(errno));
return 1;
}
sprintf(cmd, "%s%s", prefix, arg);
in = popen(cmd, "r");
if (!in) {
fprintf(stderr, "%s: popen: %s\n", argv[0], strerror(errno));
return 1;
}
while (fscanf(in, "%s", buf) == 1)
printf("%s: got [%s]\n", argv[0], buf);
if (ferror(in)) {
fprintf(stderr, "%s: fread: %s\n", argv[0], strerror(errno));
return 1;
}
else if (!feof(in)) {
fprintf(stderr, "%s: %s: unconsumed input\n", argv[0], argv[1]);
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如:
$ zcat file.gz
Every good boy does fine.
$ ./gzread file.gz
./gzread: got [Every]
./gzread: got [good]
./gzread: got [boy]
./gzread: got [does]
./gzread: got [fine.]
Run Code Online (Sandbox Code Playgroud)
不使用
sprintf(cmd, "zcat %s", argv[1]);
popen(cmd,"r");
Run Code Online (Sandbox Code Playgroud)
打开 .gz 文件。正确转义 argv[1] 。否则,您可能会遇到漏洞,尤其是当某些人注入参数 argv[1] 时,例如
123;rm -rf /
Run Code Online (Sandbox Code Playgroud)
把上面的指令改成已经有帮助了
sprintf(cmd, "zcat \'%s\'",argv[1]);
Run Code Online (Sandbox Code Playgroud)
您可能还想转义诸如 '\0'、'\''、'\;' 之类的字符 等等。