【问题标题】:Why returned FILE* retains data when command in popen() fails为什么当 popen() 中的命令失败时返回的 FILE* 保留数据
【发布时间】:2017-11-02 05:32:29
【问题描述】:

我正在开发一个使用 popen() 查找文件的程序。然后将 popen() 返回的流中的数据复制到一个 char 数组中并打印出来。

#include <iostream>
#include <cstdio>
#include <cstring>

int main()
{
        char command[1024];
        char ch = 'a';
        FILE* pf;
        while(ch < 'd')
        {
                sprintf(command, "find /home/ypatil/interest -name \\%c.out", ch);
                std::cout << std::endl << command << std::endl;
                pf = popen(command, "r");
                if(pf)
                {
                        char src[256];
                        fgets(src, 256, pf);
                        std::cout << std::endl << "pf = " << src << std::endl;  
                }
                pclose(pf);
                ++ch;
        }
        return 0;
}

现在,我正在循环执行此操作,我发现如果正在搜索的文件程序不存在,则文件流pf 将保留其旧值。我的系统上只存在a.out 文件。所以,这个程序的输出是 -

find /home/ypatil/interest -name \a.out

pf = /home/ypatil/interest/a.out


find /home/ypatil/interest -name \b.out

pf = /home/ypatil/interest/a.out

find /home/ypatil/interest -name \c.out

pf = /home/ypatil/interest/a.out

因此,您可以看到 find 正在搜索不同的文件,并且只有 a.out 存在。因此,其他文件将失败。但是,pf 仍然在每次迭代中保留其数据。我想知道为什么它保留了popen 在之前的迭代中返回的FILE * 的值。 谢谢。

【问题讨论】:

  • 您要求popen 执行find 程序,它会这样做。 find 程序是否失败与popen 仍然执行它无关。
  • 另一方面,有些事情却做不到。例如,即使popen 失败并返回空指针,您也无条件地 调用fflush(pf)。你打电话给fgets没有检查它是否成功!
  • @Someprogrammerdude - 我的问题是为什么 FILE* pf 数据即使查找失败也保持不变?当 find 命令找不到给定文件时,它在标准输出上不返回任何内容。使用 fgets() 的全部意义在于证明 FILE* pf 指向下一次迭代中的先前数据。 pf 不应该有新的价值吗?
  • popenFILE 指针不是这样工作的。 popen 函数只会返回一个空指针(你不应该将它传递给fflush!)如果它不能真正执行程序。程序执行,但没有输出,fgets 检查返回一个空指针!
  • Yiur 声明可以分为两部分。一,那个 fgets 成功地从文件中读取了一个新行;第二,该行与先前从完全不同的文件中读取的行神秘地相同。现在你明白了,如果第一个说法被证明是不真实的,那么就没有新的线可以与其他线进行比较了吗?你能验证或伪造第一个声明吗?

标签: c++ linux pipe popen glibc


【解决方案1】:

find失败时不应该为NULL吗?

不,它应该是一个有效的FILE *,体现了find 进程的管道输出。如果进程没有产生任何输出,读取它会立即产生 EOF。在这里启动 find 进程并没有失败:它只是没有找到任何东西。

不清楚你为什么不这么认为。

【讨论】:

  • 因此,当查找过程失败时,它不会发送任何输出。那么,不应该 FILE * pf 指向 EOF,而不是保存输出流中的旧数据吗?
  • '指向 EOF' 是没有意义的,并且'指向'任何东西都与 NULL 值不同。 FILE * 指向 FILE 类型的对象,如果它为空,则通过它读取应该产生立即 EOF。我已经说了这么多。而且由于您没有检查 EOF,因此您没有任何理由相信它没有被生产。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2013-08-20
  • 2018-08-20
  • 1970-01-01
相关资源
最近更新 更多