c - 为什么 fgets 不能从 popen 流中获取所有字节

标签 c popen fgets

我编译了下面的代码并运行:

$ ./run_curl 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz'

但是我无法获取要下载的文件的完整字节。为什么?

我使用 curl --silent 'http://ftp.gnu.org/gnu/grep/grep-2.4.tar.gz' > a.tgz 会得到完整的字节。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 512

void download_pkg(const char* url)
{
    char content[SIZE] = {0};
    FILE *fp = NULL;
    char cmd[255] = {0};
    FILE *fp_download = fopen("a.tgz", "w");
    sprintf(cmd, "curl --silent '%s'", url);
    fp = popen(cmd, "r");
    while(fgets(content, SIZE - 1, fp) != NULL) {
        fputs(content, fp_download);
    }
    fclose(fp_download);
    pclose(fp);
    return;
}

int main(int argc, char *argv[])
{
    download_pkg(argv[1]);
    return 0;
}

编辑:

根据 Jonathan Leffler 的 answer ,问题通过以下代码解决:

int size_read = 0;
while((size_read = fread(content, sizeof(char), SIZE - 1, fp)) > 0) {
    fwrite(content, sizeof(char), size_read, fp_download);
}

最佳答案

gzipped tar 文件将包含大量空字节。这些空字节会搞砸通过 fgets() 读取的数据的处理。您将错过空字节和它们之后的任何其他字节。 fgets() 不会告诉您它读取了多少字节,因此您无法安全地读取空字节。

您很可能需要使用 fread()fwrite()。至少,那些人不会被数据中嵌入的空值所混淆。

关于c - 为什么 fgets 不能从 popen 流中获取所有字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29052657/

相关文章:

c++ - 为什么未初始化的 const 成员在 C 中的处理方式与在 C++ 中的处理方式不同?

c++ - 在 C++ 中将变量(char)传递给 popen

Python:一个线程中的进程阻止另一个线程中的进程完成

c - fgets() 在输入时创建另一个字符串副本?

c - scanf 之后 fgets 不起作用

C Pipe() 和 fork()

c - 错误 "expression must have a constant value"

c++ - -L 和 -l 命令在 Makefile 中不起作用

Python:with open 第二次不读取任何内容

C:使用 fread()/fgets() 而不是 fgetc() 逐行读取文本文件(具有可变长度行)( block I/O 与字符 I/O)