【问题标题】:Reading gcc output in a string读取字符串中的 gcc 输出
【发布时间】:2015-03-24 03:27:47
【问题描述】:

如果我们通过system()函数执行gcc来编译一个源文件,我怎样才能将gcc的输出捕获到一个字符串中?


我尝试使用popen,只要它读取类似"PAUSE" 的内容,它就可以工作,但不适用于 gcc,因为它运行一个新的子进程。

【问题讨论】:

  • 在 fork/exec 之前使用 pipe(2) 和 dup2(2) 来重定向 stdin/stdout。
  • 你在说什么输出?编译好的文件?错误信息?
  • @rici 控制台输出。这是我认为的错误消息。
  • pipe/dup2 的 Windows 等效项是 DuplicateHandle 和 CreatePipe。

标签: c windows redirect gcc stdout


【解决方案1】:

有很多方法。

简单的方法: 将输出重定向到临时文件,并将临时文件读入字符串。

您可以使用管道。在子进程中,将输出重定向到管道并从管道的另一端读入字符串。 见man pipe

//In the parent process
int fd[2]
pipes(fd);

//Use fork+execv instead of system to launch child process.
if (fork()==0) {
    //Redirect output to fd[0]
   dup2(fileno(fd[0]), STDOUT_FILENO);
   dup2(fileno(fd[0]), STDERR_FILENO);
   //Use execv function to load gcc with arguments.

} else {
  //read from the other end fd[1]
}

请参阅http://ubuntuforums.org/archive/index.php/t-1627614.html 的帖子。

另见In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?

对于 Windows,此链接可能会对您有所帮助。 https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx Flow 与 Linux 几乎相同。语法和原语可能不同。在这里,想法是使用管道并将流程输出文件重定向到您的管道文件。

【讨论】:

  • 是的,简单的方法几乎是每个人一开始就想到的。然而,他们意识到这可能很简单,但肯定不是最好的方法。另一方面,这个链接的内容看起来相当复杂。我怀疑它会涉及 pid id 和类似的东西。
  • 特别复杂,给定windows标签:-)
  • 我不喜欢窗户。但是我的项目卡在了 windows 中,我相信这对现在的许多人来说是一个常见的情况。
  • @DeltaProxy:查看编辑。我希望这个代码布局可以帮助你。
  • 没问题。我还有解决办法。
【解决方案2】:

如果您尝试阅读由gcc 生成的错误消息,您需要记住它们是发送到stderr,而不是stdoutpopen 捕获 stdout 但不重定向 stderr

如果 Windows 上的 system 提供标准的 posix shell,您可以通过添加重定向 2>&1 在您提供给 popen 的命令行中将 stderr 重定向到 stdout

【讨论】:

  • 哦。好话。这是有道理的,但也确实更难实现。
  • @DeltaProxy:在 Unix 上,这将是微不足道的;你只需做popen("gcc -o a.out file.c 2>&1", "r"); 或类似的东西。也许这将适用于您的环境。
  • 它起作用了……在某种程度上。部分。它重定向符号^ 以及一些空间。但是它必须重定向源文件目录的反斜杠,这意味着它将被读取为转义序列,这将是一个问题。
  • @DeltaProxy:为什么会被解读为逃避? fread(或fgets)只读取文件中的字节。 (Windows 上非二进制文件的行尾翻译除外。)
  • @DeltaProxy:另外,如果你有一个令人惊讶的最新版本的 gcc,你应该调查选项-fno-diagnostics-show-caret
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多