如何在没有初始大小的情况下允许用户输入数组?

时间:2016-11-27 19:55:38

标签: c arrays

当我们事先不知道它的大小时,我一直在阅读有关如何声明数组的内容。据我所知,这样做的方法是为用户输入的数组分配一些内存,然后根据需要重新分配或释放。对于一系列字符,我是这样做的:

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

int main()
{
    //allocation of memory
    char *a = malloc(200 * sizeof(char));

    //allow user input
    fgets(a, 200, stdin);

    int i = 0;

    //find the length of the array
    int lstring = strlen(a);

    printf("%d", lstring-1);

    free(a);

    return 0;
}

这里用户没有输入char数组的实际大小,但可以通过查看字符串结尾的位置来了解它。

另一方面,对于一个整数数组,我有这个:

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

int main()
{
    //allocation of memory
    int *b = malloc(200 * sizeof(int));

    b[0] = 2;
    b[1] = 76;
    b[2] = 123;

    printf("%d", b[0]);

    free(b);

    return 0;
}

我的问题是,如何让用户输入整数?

我想到的第一件事就是用for创建一个scanf()循环,但除非允许用户首先输入数组的大小,否则这不会起作用。在没有让用户明确输入大小的情况下,是否有一种方法(相当于或不是针对char数组注意到的方法)?

2 个答案:

答案 0 :(得分:3)

  

我想到的第一件事就是用for创建一个scanf()循环,但除非允许用户首先输入数组的大小,否则这不会起作用。在没有让用户明确输入大小的情况下,是否有一种方法(相当于或不是针对char数组注意到的方法)?

您走在正确的轨道上...... 使用特殊/标记值,以了解用户输入的结束,例如此处我使用-1表示用户输入的结束

//allocating memory
int *b = malloc(200 * sizeof *b);

//notify the user with a message:
printf("enter -1 to stop entry\n");

//loop to scan user entries
for(int i = 0; i < 200; i++){
    //scanning user's input
    scanf("%d", &b[i]);

    //break when user enters -1
    if(b[i] == -1){ 
        break;
    }
}

此外,您可以使用-1,因为您使用'\0'字符串来标记其结尾。例如:

int length = 0; //variable to know length of array

//printing all the values of int array and knowing its length:
for(int i = 0; b[i] != -1; i++){
    //for printing array elements
    printf("%d ", b[i]);

    //to know the length
    length++; 
}

如果用户输入的整数数超过预期值,该怎么办?

每次达到最大值时,你可以使用realloc和双数组的大小

例如:

int max_entry = 100; //instead you can initialise max_entry by taking user's input 

//allocating memory
int *b = malloc(max_entry * sizeof *b);

//notify the user with a message:
printf("enter -1 to stop entry\n");

//loop to scan user entries
for(int i = 0; ; i++){
    scanf("%d", &b[i]);

    if( i == max_entry - 1 && b[i] != -1){
        //increasing max entry
        max_entry *= 2;

        //reallocating to increase size of array
        int *temp = NULL;
        temp = realloc(b, max_entry * sizeof *b);

        if(temp == NULL){
            //allocation failed, handle it
        }
        else{
            b = temp;
        }
    }

    //break when user enters -1
    if(b[i] == -1){ 
        break;
    }
}

答案 1 :(得分:2)

是的,您可以使用realloc()。一种常见的方法是创建一个可以扩展的结构,它将代表您的数组。结构可以如下所示:

typedef struct
{
    int allocated; // Here you can save how many elements you have allocated space for
    int used; // Here is how many elements are in the array
    int * array; // here is pointer to the array

} Array;

然后你应该创建一个初始化这个Array结构的函数:

void initArray(Array * a)
{
    a->allocated = INIT_SIZE;
    a->used = 0;
    a->array = malloc(INIT_SIZE * sizeof(int));
}

现在数组已初始化,您已为INIT_SIZE元素分配了内存。现在最重要的部分 - 实际上添加元素。您还可以为此创建一个函数:

bool insertEl(Array * a, int el)
{
    if(a->used == a->allocated) //If there is no more space, then we need to realloc
    {
        int * temp = realloc(a->array, 2 * a->allocated * sizeof(int));
        if(!temp) // Just check if realloc succeeded
        {
            printf("Reallocation failed!\n");
            return false;
        }
        a->array = temp;
        a->allocated *= 2;
    }

    a->array[a->used] = el;
    a->used++;

    return true;
}

由于重新分配是相当昂贵的操作,因此最好增加分配元素的数量而不仅仅是一些常量。我通常加倍空间。由于您使用malloc()realloc()来分配内存,因此您应该{I}完成内存后使用free()

void freeArray(Array * a)
{
    free(a->array);
    a->array = NULL;
    a->allocated = 0;
    a-> used = 0;
}

一旦你有了这样的数组结构,你可以循环运行scanf(),直到EOF,并且在每个周期中,你scanf()输入和使用insertEl()函数将其添加到数组中。