Reputation: 1117
I've been reading about how to declare an array when we don't know its size beforehand. As far as I understand, the way to do it is by allocating some memory for the array input by the user, and then reallocating it or freeing as needed. For an array of characters I was doing it in this way:
#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;
}
Here the user doesn't input the actual size of the char array, but it can be known by looking at the position of the end of string character.
On the other hand, for an array of integers I have this:
#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;
}
My question is, how can I allow the user to input the integers?
The first thing that came to my mind was to create a for
loop with a scanf()
, but that is not going to work unless one allows the user to enter the size of the array first. Is there a way (equivalent or not to the one noticed for a char array) of doing this without letting the user explicitly enter the size?
Upvotes: 3
Views: 4030
Reputation: 5457
The first thing that came to my mind was to create a
for
loop with ascanf()
, but that is not going to work unless one allows the user to enter the size of the array first. Is there a way (equivalent or not to the one noticed for a char array) of doing this without letting the user explicitly enter the size?
You are on the right track... Use a special / flag value, to know the end of user's entry for example here I used -1
to denote the end of user's entry
//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;
}
}
further you can use the -1
as you'd use '\0'
for a string to mark its end. for example:
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++;
}
What if user enters more than expected number of integers?
Well you can use realloc
and double array's size every time it hits maximum value
For example:
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;
}
}
Upvotes: 3
Reputation: 957
Yes, you can use realloc()
for this. A common approach to this is to create a struct, that will represent you array, that can be expandable. The struct can look like this:
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;
Then you should create a function, that will initialize this Array structure:
void initArray(Array * a)
{
a->allocated = INIT_SIZE;
a->used = 0;
a->array = malloc(INIT_SIZE * sizeof(int));
}
Now the array is initialized, you have allocated memory for INIT_SIZE
elements. Now the most important part - actually adding elements. You can also create a function for this:
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;
}
As reallocation is pretty expensive operation, it's good idea increase the number of allocated elements more than just some constant. I usually double the space. Since you used malloc()
and realloc()
to allocate the memory, you should free()
it once you're done with it:
void freeArray(Array * a)
{
free(a->array);
a->array = NULL;
a->allocated = 0;
a-> used = 0;
}
Once you have an Array structure like this, you can the run scanf()
in cycle until there's an EOF
, and in each cycle, you scanf()
the input and use insertEl()
function to add it to the array.
Upvotes: 2