C 拆分 CMD 参数

2023-12-15

我正在尝试做某事,但我可以。我有一个 C 程序,我想在其中解析所有参数。让我们更具体一点

EDIT:我在缓冲区中读取命令,而不是在程序以 argv 等启动时读取命令。 我使用 fgets 从 STDIN 读取命令

假设我读了这样的命令行:

ls -la

我想将命令和参数列表保存在n这种格式的数组:

char ***command; // A list of lists of strings.

command[0][0] = "ls";
command[0][1] = "-l";
command[0][2] = "a";
command[0][3] = NULL;

我想使用 execvp 执行上述命令,这就是我想要这种格式的原因。另请看下面的示例

ls -la | grep 1

该数组必须如下:

command[0][0] = "ls";
command[0][1] = "-l";
command[0][2] = "a";
command[0][3] = NULL;
command[1][0] = "grep";
command[1][1] = 1;
command[1][2] = NULL;

因此,简而言之,我想拆分命令并将它们放入基于字符 | 的二维数组中。但也要保留命令参数。

我尝试使用 strtok (空格字符分隔符)来做到这一点,然后将它们存储在数组中,但我失败了。

你能帮我吗?

谢谢


下面的答案显示了如何拆分 C 字符串,就像 shell 在将其传递给main充当argc and argv。那是ls -la将分为:

argv[0] == "ls"
argv[1] == "-la"

但是,由于您想要包含多个用管道字符粘在一起的命令行,因此您首先必须在每个命令行中拆分字符串|特点。这可以使用以下方法完成strtok正如你提到的。

str = "ls -la|grep hello";
...
// Do split on |
...
strs[0] == "ls -la";
strs[1] == "grep hello";

然后进一步将这些命令行分割成自己的argv数组。然后最后将它们组装成一个数组NULL正如您所描述的那样。

因为当你开始时你不知道最终数组的大小。或者就此而言有多少|有迹象表明,您可以首先计算这些并分配一个包含所有argvs:

char **strs = NULL;
char **argvs = NULL;
size_t count = 0;
size_t i = 0;
while (*str) if (*str++ == '|') ++count;

strs = calloc(count, sizeof(char *));

...
// strtok on | and save tokens into strs[i]
...

现在分割命令行并附加NULL在最后:

// Code for split_commandline below.
for (i = 0; i < count; i++)
{
    argvs[i] = split_commandline(strs[i], &argc);

    // Make room for NULL at the end of the argv array.
    argvs[i] = realloc(argvs[i], (argc + 1) * sizeof(char *));
    argvs[i][argc] = NULL;
}

所有这些都有点做作,当然可以使用存储,但这样做的步骤很清晰。

NOTE: 这个不分裂"ls -la" into "ls", "-l", "a"正如最初的问题所要求的那样,而是"ls", "-la"。我不确定为什么需要这样做,但它需要对单个命令进行黑客攻击,因为什么"-la"手段特定于ls程序。

分割命令行

Unix/Linux您可以使用wordexp对于这件事。然而,这并不意味着您应该意识到这会带来一些安全隐患。也就是说,它将扩展 shell 变量,并且许多(如果不是全部)实现都会导致调用sh.

注意:OSX 10.9.5 似乎会泄漏内存wordexp即使wordfree叫做。看OSX 10.9.5 上 libc 中的 wordexp 是否存在泄漏?了解详情。

Windows我知道这个问题只针对 Linux。但其他人可能对多平台解决方案感兴趣。

在这里你可以使用CommandLineToArgvW。请注意,这是为了wchar_t *所以下面的示例代码首先从char * to wchar_t *,进行分割,然后转换回char *为两个平台获得一致的 API。

写完这个实现后我还发现__getmainargs它支持char *相反,但我还没有尝试使用这个。

代码示例:

char **split_commandline(const char *cmdline, int *argc)
{
    size_t i;
    char **argv = NULL;
    assert(argc);

    if (!cmdline)
    {
        return NULL;
    }

    // Posix.
    #ifndef _WIN32
    {
        int ret;
        wordexp_t p;
        memset(&p, 0, sizeof(p));

        // Note! This expands shell variables (might be a security issue).
        if ((ret = wordexp(cmdline, &p, 0)))
        {
            return NULL;
        }

        *argc = p.we_wordc;

        if (!(argv = calloc(*argc, sizeof(char *))))
        {
            goto fail;
        }

        for (i = 0; i < p.we_wordc; i++)
        {
            if (!(argv[i] = strdup(p.we_wordv[i])))
            {
                goto fail;
            }
        }

        // Note that on some OSX versions this does not free all memory (10.9.5)
        wordfree(&p);

        return argv;
    fail:
        p.we_offs = 0;
        wordfree(&p);
    }
    #else // WIN32
    {
        // TODO: __getmainargs is an alternative... https://msdn.microsoft.com/en-us/library/ff770599.aspx
        wchar_t **wargs = NULL;
        size_t needed = 0;
        wchar_t *cmdlinew = NULL;
        size_t len = strlen(cmdline) + 1;

        if (!(cmdlinew = calloc(len, sizeof(wchar_t))))
        {
            goto fail;
        }

        if (!MultiByteToWideChar(CP_ACP, 0, cmdline, -1, cmdlinew, len))
        {
            goto fail;
        }

        if (!(wargs = CommandLineToArgvW(cmdlinew, argc)))
        {
            goto fail;
        }

        if (!(argv = calloc(*argc, sizeof(char *))))
        {
            goto fail;
        }

        // Convert from wchar_t * to ANSI char *
        for (i = 0; i < *argc; i++)
        {
            // Get the size needed for the target buffer.
            // CP_ACP = Ansi Codepage.
            needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
                                        NULL, 0, NULL, NULL);

            if (!(argv[i] = malloc(needed)))
            {
                goto fail;
            }

            // Do the conversion.
            needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
                                        argv[i], needed, NULL, NULL);
        }

        if (wargs) LocalFree(wargs);
        free(&cmdlinew);
        return argv;

    fail:
        if (wargs) LocalFree(wargs);
        free(&cmdlinew);
    }
    #endif // WIN32

    if (argv)
    {
        for (i = 0; i < *argc; i++)
        {
            if(argv[i]) free(argv[i]);
            argv[i] = NULL;
        }

        free(argv);
    }

    return NULL;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 拆分 CMD 参数 的相关文章

  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 我怎么知道PowerShell函数参数被省略了

    考虑这样的函数 function Test foo bar 我们可以称之为 Test foo null Test 我如何知道何时省略了 foo 以及何时为 null 如果您使用的是 Powershell V2 或更高版本 则可以使用 PSB
  • 过滤 stderr 并获取初始返回代码

    在 shell 脚本中 我必须运行一个命令 我需要确定返回码是什么 但事实证明该命令的输出会发送到 stderr 并且还会输出用户的密码 不幸的是 这是命令的一个参数 不好 我知道 我至少想过滤掉密码 使其不被显示回来 cmd OPTION
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • 私有模板函数

    我有一堂课 C h class C private template
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub

随机推荐

  • ActualWidth 作为 From WPF 动画的值

    为什么我不能参考ActualWidth作为一个值 我可以在代码中使用它 XAML
  • Javascript 和 ESLint 中的全局变量

    我有多个 javascript 文件 并且在一个文件中定义了一些全局变量 该变量先于其他文件加载 因此 第一个文件之后加载的所有文件都可以访问全局变量 然而 ESLint 将全局变量显示为 未定义 我不想改变 ESLint 的规则 我想找到
  • noRollbackFor 并不总是处理未经检查的异常(不重复)

    我见过很多类似的问题 但它们通常与我的问题无关 这是我的代码 Override class implements interface can also add rollbackFor OutOfMemoryError class here
  • Android Studio 中的 lint 如何与 IntelliJ 检查集成?

    据我所知 Android Studio中有两种类型的检查 一种是从IntelliJ继承的 另一种是从lint继承的 参见 命令行上的 Android lint 缺少问题组 与 Android Studio 中提供的选项相比 我还了解到 当您
  • 我可以使用 Arrays.asList 创建数组列表吗?

    假设我想创建一个包含 Integer 数组的列表 但 Integer foo 1 2 3 List
  • 如何在 php 中以编程方式从选项卡获取 IMEI 号码 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 当我的网页加载到浏览器中时 我需要从 Android 设备获取 IMEI 号码 页面将用
  • 在 Thinking Sphinx 中使用 Delta 索引进行关联

    我有一个产品型号 class Product lt ActiveRecord Base belongs to subcategory define index do fields indexes subcategory name as gt
  • 如何将 PHP 数组参数传递给 Javascript 函数?

    index php
  • 如何向所有用户授予我的应用程序创建的文件的完全权限?

    我开发的工具需要授予对其创建的文件 完全控制 访问权限 需要从所有 Windows 帐户甚至未来可能的帐户中读取 修改和删除它 这能实现吗 我知道我可以为特定用户尝试这个 FileSystemAccessRule rule new File
  • Xamarin.iOS 本机链接错误 MTOUCH MT5210 未定义符号 std::string

    我的 Xamarion iOS 绑定项目具有指向所有必需的本机视频 SDK 库和本机操作系统框架的链接 我已经使用 Frameworks 属性设置了所需的框架 其他设置包括 SmartLink true ForceLoad true IsC
  • ClearCase 不允许签入

    我对 ClearCase 相当陌生 但已经搜索了以下问题的很多解决方案 但没有成功 当我尝试办理登机手续时 出现以下错误 我的文件 检查时出错 没有权限执行 签入 操作 必须是以下之一 对象创建者 元素所有者 VOB 所有者 ClearCa
  • Neo4j 因果集群优于高可用性集群

    我们正在将 HA 集群迁移到因果集群 从 HA 集群迁移到因果集群有什么真正的优势吗 目前仅使用 REST 端点 是否可以仅使用两个 Neo4j 实例进行因果聚类 谢谢 因果集群是新一代的 Neo4j 集群 它将随着新版本的发布而不断发展
  • 实现 NHibernate 嵌套事务行为

    我正在尝试使用 NHibernate 的事务控制和 FlushMode 选项来实现某种嵌套事务行为 但是在阅读过多之后事情变得有点混乱 因此对我下面列出的事实的任何确认都将非常有用 我想要的是打开一笔大交易 然后拆分成小交易 想象一下以下场
  • 通过将 data.frame 的列名传递到 apply() 或 plyr 函数来替换所选列中的值

    假设我有一个 date frame 像 df lt data frame a 1 5 b sample 1 5 5 replace TRUE c 5 1 df a b c 1 1 4 5 2 2 3 4 3 3 5 3 4 4 2 2 5
  • 在 R 中创建重复向量序列[重复]

    这个问题在这里已经有答案了 我需要一些帮助 如何创建以下向量序列 1 1 1 1 2 2 2 3 3 4 我尝试使用 rep 和 seq 但仍然不成功 尝试这个 rep 1 4 4 1 Output 1 1 1 1 1 2 2 2 3 3
  • “cscript //NoLogo”代表什么?

    这是一个java程序代码 运行记事本程序并粘贴存储在该程序本身中的特定文本 我想知道你能否向我解释一下String vbs值 以及File file 以及 cscript NoLogo file getPath in the Process
  • 只检索更改的文档字段

    我发现监听文档变化会总是一遍又一遍地下载完整的文档 在以下情况下我遇到问题 文档的大小正在接近1 MiB 这是文档大小的限制 现在 有一个number场即仅字段更新 这只是几个字节 但是 收听此更改 例如对帖子的点赞 将始终下载完整的1 M
  • Firefox 在伪元素周围添加了奇怪的空间

    看看这些照片 JSFiddle链接在底部 firefox chrome 它们都是从 chrome 和 Firefox 中获取的相同元素 正如您所看到的 来自 Firefox 的元素在其顶部和左侧周围有一些空间 但来自 chrome 的元素没
  • Dompdf 在 Laravel 中封装其他语言支持

    我在 laravel 项目中使用 dompdf 包创建了我的 pdf 但是当我想渲染其他语言 孟加拉 而不是英语时 显示 div style margin 50px padding 10px div align center h2 Anti
  • C 拆分 CMD 参数

    我正在尝试做某事 但我可以 我有一个 C 程序 我想在其中解析所有参数 让我们更具体一点 EDIT 我在缓冲区中读取命令 而不是在程序以 argv 等启动时读取命令 我使用 fgets 从 STDIN 读取命令 假设我读了这样的命令行 ls