从动态分配的数组中调用值

时间:2016-02-24 21:24:11

标签: c arrays pointers command-line

我尝试编写一个程序,它接受命令行输入(应该是数字)并将它们存储在一个动态分配的数组中,通过访问数组打印出来。但是,它会打印随机值。

#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    int *list_nums;
    list_nums = malloc(argc * sizeof(int));
    for (i = 1; i < argc; i++) {
        list_nums[i-1] = argv[i];
    }
    printf("you entered: ");
    for (i = 0; i < argc-1; i++) {
        printf("%d, ", list_nums[i]);
    }
    return 0;
}

最初,我在第二个for循环中使用了print语句:

        printf("%s, ", list_nums[i])  // %s instead of %d

因为argv[]设置为char,但这会给我一个分段错误。这是怎么回事?

3 个答案:

答案 0 :(得分:1)

您的方法存在的问题是您要将argv元素分配给int数组。由于argv元素是C字符串,因此您需要解析它们才能获得int

for (i = 1; i < argc; i++) {
    list_nums[i-1] = atoi(argv[i]);
}

在课程结束时忘记free(list_nums)

包括<stdlib.h>以使用atoi

答案 1 :(得分:1)

尝试以下

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

int main(int argc, char *argv[]) {
    int i;
    int *list_nums = NULL;

    if ( argc > 1 ) list_nums = malloc( ( argc - 1 ) * sizeof( int ) );

    for ( i = 1; i < argc; i++ ) {
        list_nums[i-1] = atoi( argv[i] );
    }

    printf("you entered: ");
    for ( i = 0; i < argc-1; i++ ) {
        printf( "%d, ", list_nums[i] );
    }
    printf( "\n" );

    free( list_nums );

    return 0;
}

注意参数的存储方式与字符数组一样。因此,您必须在int类型的对象中转换包含数字的字符串。

答案 2 :(得分:1)

始终注意编译器的警告。如果您没有收到任何警告,请检查您的编译器设置。

$ gcc -Wall -O a.c
a.c: In function ‘main’:
a.c:6:5: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
     list_nums = malloc(argc * sizeof(int));
     ^
a.c:6:17: warning: incompatible implicit declaration of built-in function ‘malloc’
     list_nums = malloc(argc * sizeof(int));
                 ^
a.c:8:24: warning: assignment makes integer from pointer without a cast
         list_nums[i-1] = argv[i];
                        ^

第一个警告说malloc未被宣布;你错过了#include <stdlib.h>。在大多数系统上,这不会导致实际问题。第二个警告是同样问题的结果。

第三个警告表明存在问题。 argv是指向char的指针数组,因此argv[i]是指向char的指针。 list_nums指向一个整数数组。所以你要指定一个整数的指针。您打印出来的随机数字是内存中参数的地址。

您可以将字符串数组复制到字符串数组中。在这种情况下,您需要将list_nums更改为char*数组,并使用%s说明符进行打印。

似乎您打算将参数解释为整数。如果要将参数(即字符串)转换为整数,则需要明确地执行此操作。您可以将atoi函数用于快速一次性代码,或strtol使用健壮的代码(atoi不允许错误检查)。

long *list_nums = malloc((argc-1) * sizeof(*list_nums));
char *end;
if (list_nums == NULL) {
    fprintf(stderr, "Not enough memory\n");
    return EXIT_FAILURE;
}
for (i = 1; i < argc; i++) {
    list_nums[i-1] = strtol(argv[i], &end, 0);
    if (*end != 0) {
        fprintf(stderr, "Invalid argument: %s\n", argv[i]);
        return EXIT_FAILURE;
    }
}
for (i = 0; i < argc-1; i++) {
    printf("%ld, ", list_nums[i]);
}