首页 > 解决方案 > 如何在 C 或 C++ 中包装参数并将它们传递给 system 或 exec*

问题描述

我想编写一个包装器,用 argv 做一些简单的事情并调用一些脚本。我有以下要求:

我最初的做法:

编写 ac 程序首先清理参数,然后将它们用引号括起来,然后调用system. 不幸的是,我无法从systemorexec*函数中获得结构良好的行为。我希望以下所有示例都输出类似的内容arg1=1; arg2=2; arg3=3; arg4=(引号换行有一些差异),但在某些示例中会出错,并在 execl 上暂停:

输入文件:

@:: test.bat
@echo off

echo arg1=%1; arg2=%2; arg3=%3; arg4=%4
//minimal-example.c
#include <Windows.h>
#include <stdio.h>

int main( int argc, char ** argv ) {
  puts("\nExample 1:");
  system("\"test.bat\" \"1\" \"2\" \"3\" ");

  puts("\nExample 2:");
  system("test.bat \"1\" \"2\" \"3\" ");

  puts("\nExample 3:");
  system("test.bat 1 2 \"3\" ");

  puts("\nExample 4:");
  system("\"test.bat\" 1 \"2\" 3 ");

  puts("\nExample 5:");
  system("\"test.bat\" 1 2 3 ");

  puts("\nExample 6:");
  execl(argv[0], "test.bat", "1", "2", "3", NULL);

  return 0;
}

输出运行:

Example 1:
'test.bat" "1" "2" "3' is not recognized as an internal or external command,
operable program or batch file.

Example 2:
arg1="1"; arg2="2"; arg3="3"; arg4=

Example 3:
arg1=1; arg2=2; arg3="3"; arg4=

Example 4:
'test.bat" 1 "2' is not recognized as an internal or external command,
operable program or batch file.

Example 5:
arg1=1; arg2=2; arg3=3; arg4=

Example 6:
arg1=1; arg2=2; arg3=3; arg4=

(示例 6 暂停,直到我按下Enter

问题:

  1. 有没有办法以允许空格的方式正确包装路径/参数system
  2. 我可以在参数中转义引号system吗?
  3. 是否有非阻塞方式运行exec*
  4. 一种exec*方法是否可以确保包装程序的标准输入标准输出和标准错误行为正确(没有奇怪的溢出或奇怪的阻塞事件?)

标签: c++cwindowscommand-line-interface

解决方案


像这样的东西应该工作:

 string cmd = "test.bat";

 for(int i = 1; i < argc; i++) {
    cmd += " ";
    cmd += argv[i]
 }

 system(cmd.c_str());

当然,其中包含空格的 args 需要通过添加引号来进一步处理,并且带有引号的参数可能需要转义,并且在 args 包含无法直接处理的内容的情况下还有许多其他复杂情况)

作为替代方案,您可以查看使用 CreateProcess 运行批处理文件


推荐阅读