c链表或二叉树中的argc/argv

c链表或二叉树中的argc/argv,c,command-line-arguments,C,Command Line Arguments,因此,我尝试制作一个链表/二叉树,并: 用户应该能够在启动程序时直接从命令行选择数据结构。这应该使用argc或argv参数作为main参数 我该怎么做?我不明白为什么不使用switch case语句询问学生 option 1: linked list option 2: binary tree? 我们没有正确地报道argc argv有人能帮忙吗 显然这是一个复制品。。。隐马尔可夫模型。。我问的是关于二叉树/链表的问题,用户会如何告诉它选择哪种数据结构 argc=参数计数

因此,我尝试制作一个链表/二叉树,并:

用户应该能够在启动程序时直接从命令行选择数据结构。这应该使用argc或argv参数作为main参数

我该怎么做?我不明白为什么不使用switch case语句询问学生

     option 1: linked list 

     option 2: binary tree?
我们没有正确地报道argc argv有人能帮忙吗


显然这是一个复制品。。。隐马尔可夫模型。。我问的是关于二叉树/链表的问题,用户会如何告诉它选择哪种数据结构

argc=参数计数,argv=参数数组。argv[0]是正在执行的程序。argv[1..n]是传递给可执行文件的参数

示例:我使用两个参数bar和bas调用可执行文件foo: 福巴巴斯酒店


argc=3,argv=[foo,bar,bas]

使用以下骨架程序进行实验,并找出答案

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s COMMAND\n", argv[0]);
        return EXIT_FAILURE;
    }

    if (!strcmp(argv[1], "foo")) {
        printf("Doing foo.\n");

    } else
    if (!strcmp(argv[1], "bar")) {
        printf("Doing bar.\n");

    } else {
        fprintf(stderr, "Unknown command line parameter '%s'.\n", argv[1]);
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
其中第一个表单告诉程序使用链表;第二种形式告诉程序使用树;其他表单只输出用法、如何调用程序的信息:

用法:./程序[-h |-help] /程序模式 其中,模式为以下之一: 链表模式 树模式 有关该程序实际功能的更多详细信息。。。 您只需很少的代码即可实现这一点:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

enum {
    NO_MODE = 0,
    LIST_MODE,
    TREE_MODE
};

int main(int argc, char *argv[])
{
    int mode = NO_MODE;

    if (argc != 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        printf("Usage: %s [ -h | --help ]\n", argv[0]);
        printf("       %s MODE\n", argv[0]);
        printf("\n");
        printf("Where MODE is one of\n");
        printf("    list    for linked list mode\n");
        printf("    tree    for tree mode\n");
        printf("\n");
        printf("Further details on what the program actually does...\n");
        printf("\n");
        return EXIT_SUCCESS;
    }

    if (!strcmp(argv[1], "list"))
        mode = LIST_MODE;
    else
    if (!strcmp(argv[1], "tree"))
        mode = TREE_MODE;
    else {
        fprintf(stderr, "%s: Unknown MODE.\n", argv[1]);
        return EXIT_FAILURE;
    }

    /* mode == LIST_MODE or TREE_MODE here,
       depending on the first command line parameter.
    */

    return EXIT_SUCCESS;
}
注意| |运算符在C中短路:如果左侧为false,则根本不计算右侧。因此,如上所述,第一个strcmp检查仅在argv==2时执行,第二个strcmp检查在argv==2时执行,并且第一个strcmp返回非零不匹配

换句话说,仅当argv!=2有少于两个或多于两个的命令行项,将程序名视为一个;或者如果唯一的命令行参数与-h或-help匹配

!!不是C中的操作员!当且仅当x为零或NULL时,x计算为1;否则为0

你可以用!!十,。如果x为零,则计算结果为零;如果x不为零,则计算结果为1。这是合乎逻辑的。这通常被称为not not操作

枚举只是提醒你,魔法常数是不好的;最好使用枚举或预处理器宏定义NO_模式0等等。在一个地方使用1表示树模式,在另一个地方使用2表示树模式,这将非常容易;这样的bug很难调试,需要阅读代码的人集中太多精力才能找到这样的bug。所以不要使用魔法常量,而是使用枚举或宏

在上面,我决定没有任何_模式的值为零,并让编译器为LIST_模式和TREE_模式分配递增的值;考虑它们的编译时间整数常量。也就是说,您可以在switch语句的case标签中使用它们

因为如果两个字符串匹配,strcmp返回零!strcpargv[1],baz为真非零当且仅当argv[1]包含字符串baz。在实际代码中,当比较字符串时,总是可以看到它

如果你看我这里的答案,你会经常看到一个If argc。。。示例代码中的用法块。这是因为,即使是我自己,也常常会在几天内忘记该计划的确切目的。我通常在我编写的机器上有几十个示例程序,而不是查看源代码以查看是否有什么东西在我的内存中移动,我只是在没有命令行参数的情况下运行示例代码段,或者实际上使用-h参数运行示例代码段,因为其中一些是过滤器,以查看它们的功能。它更快,阅读更少,我会更快地找到相关的代码片段


总之,在您的所有程序中编写一个使用输出块,尤其是当它只是一个测试程序而您不会在任何地方发布时。它们很有用,特别是当你有一个充满了它们的库,在它们自己的目录中有各种各样的代码片段;我使用一个四位数的数字和一个简短的描述性名称来实现有趣或有用的东西。从长远来看,这节省了时间和精力,任何让我变得高效和懒惰的事情在我的书中都是好的。

@Tormund Giantsbane Uhhno@Coder这是对试图帮助别人的人非常无礼的回应。也许你可以进一步说明Tormund的链接并不能回答你的问题。对不起。。我更新了它的开关/外壳,argc/argv不是或。您希望您的开关/案例如何从用户处获得输入,以指示数据结构的类型?您太专注于在链表或二叉树之间进行选择。。他们可能会在香蕉和雨伞之间做出选择,关键是您需要学习如何访问和解析命令行参数。菜单驱动程序,如选择选项:\n 1。链接列表\n 2。二叉树\n 3。退出就可以了。用户将如何选择二叉树或链表?在看不到任务要求的情况下,这实际上取决于您如何组织和编写程序以及参数的用途。@编码器希望用户输入表示选择的字符串或数字,然后选中w
没有要求,只是说我不知道从哪里开始,也不知道用户如何选择哪个数据结构。所以,如果这是我的任务,我会让用户传递一个参数,比如1或2来选择结构,然后在程序内部对该参数进行测试/切换,很可能是argv[1].有一个问题,这是什么意思!在stcmpalso运行之前,用户如何知道输入什么?我不能执行代码,除非他们键入完全相同的代码same@Coder:如果您需要进一步澄清,请告诉我。我决定展示一个完整的工作示例,即使有一点风险,您可能会在不理解它的情况下将其逐字地用作自己的工作;为了确保这种情况不会发生,我明确表示,你的助教/老师只需问一两个问题就可以抓住你。所有这些都在本文中解释,一点也不难,所以如果你费心阅读本文,理解代码是如何工作的、为什么工作的,以及为什么它应该以这种方式工作,那么你就遥遥领先了。这应该是值得努力的。