将参数作为终端的输入

时间:2016-10-18 04:13:52

标签: c segmentation-fault arguments

这是一个函数的一部分,它从终端获取输入并根据输入的内容对它们进行排序(排序类型,要使用的排序方法的版本/变体以及数组的大小)。这就是我到目前为止所做的:

int main(int argc, char * argv[]) { //will have 3 arguments not including function name: sortingtype, version and arr size
    int * arr = make_arr(argv[2], argv[3]); //[2]

    if (strcmp(argv[1], "sortingtype1") == 0) {
        SortingType1(arr, argv[3]); //[2][3]
    }
    else if (strcmp(argv[1], "sortingtype2") == 0) {
        SortingType2(arr, argv[3]); //[2][3]
    }
    else {
        return 0;
    }
}

void test(){ //[1]
    main("sortingtype1", "a", 10); //sortingtype, version and arr size
}

[1]我有一个函数test()来模拟来自终端的输入,但我不知道它是否以这种方式工作。我得到一个错误,说主要参数太多了。

[2]无论我是否删除了该测试函数,我仍然会收到有关“传递参数(带有argv [X]的参数)的警告”,而不是使用强制转换“。

[3]这些也需要输入int而不是char *,如何更改它们?

有关如何解决这个问题的任何建议?我已经看过使用sscanf的解决方案,但更喜欢在我的技能水平上更基本的解决方案,以便理解。

编辑:来自

的细分错误
int * SortingType2(int * arr, int len) {
    for (int i=1; i < len; i++) {
        int x = arr[i];
        int j = i;
        while ((j > 0) && (x < arr[j-1])) {
            arr[j] = arr[j-1];
            j--;
        }
        arr[j] = x;
    }
    return arr;
}

int main(int argc, char * argv[]) {
    int size;
    if (argc > 3) size = atoi(argv[3]);

    int * arr = make_arr(argv[2][0], size);

    if (strcmp(argv[1], "sortingtype1") == 0) {
        SortingType1(arr, size);
    }
    else if (strcmp(argv[1], "sortingtype2") == 0) {
        SortingType2(arr, size);
    }
    else {
        return 0;
    }
}

2 个答案:

答案 0 :(得分:1)

如果要从函数调用main(),则必须传递参数计数和指向空终止的字符串数组的指针(有关详细信息,请参阅What should main() return in C and C++?)。 / p>

因此,你可以写:

void test(void)
{
    char *argv[] = { "sortingtype", "a", "10", 0 };
    main(3, argv);
}

这样做并不常见。您的代码中没有证据表明正在调用test()函数。

请注意,参数在上面显示的代码中不是可修改的字符串;通常,参数是可修改的。如果这很重要,你必须更努力地工作:

void test(void)
{
    char arg0[] = "sortingtype";
    char arg1[] = "a";
    char arg2[] = "10";
    char *argv[] = { arg0, arg1, arg2, 0 };
    main(3, argv);
}

另请注意argv中的所有参数都应该是字符串。您的原始代码似乎尝试传递10而不是"10",但在参数向量中不允许这样做(当然,10可以作为参数计数有效)。

请注意,递归调用main()是一件非常古怪的事情。它实际上很少是必要的,也不是最理想的。然而,它在C语言中是合法的 - 但它在C ++中是不合法的。

答案 1 :(得分:1)

argv[]是一个字符串数组,因此如果需要整数,则需要转换它们。最简单的方法是使用atoi()sscanf()atoi()位于stdlib.hsscanf()位于stdio.h。使用atoi(),您只需给它一个字符串,然后返回int。使用sscanf(),您可以提供字符串,转换说明符和变量地址,就像在scanf()函数中一样,不同之处在于您在扫描字符串而不是stdin。这是一个例子:

#include <stdio.h>   // needed for atoi()
#include <stdlib.h>  // needed for sscanf()

int main(int argc, char *argv[])
{
    int i = 0;
    int j = 0;

    /* if argv[1] exists, convert to int */
    if (argc > 1)
        i = atoi(argv[1]);

    /* if argv[2] exists, convert to int */
    if (argc > 2)
        sscanf(argv[2], "%d", &j);

    printf("%d -- %d\n", i, j);

    return 0;
}

如果您编译此代码并执行它,您将获得,例如:

david scratch λ> ./a.out 123 456
123 -- 456

使用您的代码:

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

int main(int argc, char * argv[])
{
    int size;

    if (argc < 4) {
        printf("Usage: %s sortingType state size\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    size = atoi(argv[3]);

    int * arr = make_arr(argv[2], size);

    if (strcmp(argv[1], "sortingtype1") == 0) {
        SortingType1(arr, size);
    }
    else if (strcmp(argv[1], "sortingtype2") == 0) {
        SortingType2(arr, size);
    }

    return 0;
}