user672518
user672518

Reputation: 95

Dynamically Growing Array Based on User Input in C

I need to create a program which:

  1. initially allocate an array to read in and hold up to 5 temperatures.
  2. prompt the user to enter temperatures and type the value -100.0 when they are finished
  3. if the user fills up the array your program should dynamically allocate a new array which is double the size.
  4. copy the old values across to the new array. deallocate the old array.
  5. continue reading into the new array.
  6. print the new array out when it's done

I'm completely new to C and I'm kinda stuck. I know how to create a dynamic array, but I don't know how to create a new array which constantly grows once the old array is filled up.

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

int main(void){
    int i,k; //loop count
    int j = 5; //initial array size
    int* temp = malloc(sizeof(int)*j); 
    int* newtemp;

    for (i = 0; i < j; i++){ //loop to read in temperature
        printf("enter temperature: ");
        scanf("%d",(temp+i));
        if (i=j){
        j = j*2; //double the size of initial array
        int* newtemp = malloc(sizeof(int)*j);
        strcpy(*newtemp,temp); // copy string
        for (k = 0; k < j; k++){ //loop to read in temperature
            printf("enter temperature: ");
            scanf("%d",(temp+i+k));
            }
        }
        switch (temp[i]){
            case (-100):
            temp[i] = '\0';
            i = 5; //loop ends
            break;
        }    
    }
    return 0;
}

The error messages:

tempp.c:18:16: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
         strcpy(*newtemp,temp);
                ^
In file included from tempp.c:3:0:
/usr/include/string.h:121:14: note: expected ‘char * restrict’ but argument is of type ‘int’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
tempp.c:18:25: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
         strcpy(*newtemp,temp);
                         ^~~~
In file included from tempp.c:3:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)

I know that my code is messy and I really don't know the right method to reallocate a new array while it constantly grows. Please help me with this. Thank you!

Upvotes: 0

Views: 3508

Answers (3)

Paweł Dymowski
Paweł Dymowski

Reputation: 840

You can try to declare two arrays, and switch between them, like that:

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

int main(void){

    int currentArraySize = 5;

    int* temperatures1 = malloc(sizeof(int)*currentArraySize);
    int* temperatures2 = NULL;
    int temperaturesSlot = 0;
    int temperature = 0;
    int index = 0;


    while(1){
        if (index == currentArraySize){
            switch (temperaturesSlot){
                case 0:
                    temperatures2 = malloc(sizeof(int)* 2 *currentArraySize);
                    memcpy(temperatures2, temperatures1, currentArraySize * sizeof(int));
                    free(temperatures1);
                    temperatures1 = NULL;
                    temperaturesSlot = 1;
                    break;
                case 1:
                    temperatures1 = malloc(sizeof(int)* 2 *currentArraySize);
                    memcpy(temperatures1, temperatures2, currentArraySize * sizeof(int));
                    free(temperatures2);
                    temperatures2 = NULL;
                    temperaturesSlot = 0;
                    break;
            }
            currentArraySize *= 2;
        }

        printf("enter temperature: ");
        scanf("%d",(&temperature));
        if (temperature == -100){
            break;
        }
        else if (temperaturesSlot == 0){
            temperatures1[index] = temperature;
        }
        else{
            temperatures2[index] = temperature;
        }
        ++index;
    }

    for (int i = 0; i < index; ++i){
        if (temperaturesSlot == 0){
            printf("%d, ", temperatures1[i]);
        }
        else{
            printf("%d, ", temperatures2[i]);
        }
    }
}

Upvotes: 0

ooj-001
ooj-001

Reputation: 180

How about using the realloc tool instead?

void printArray(double *array, int size){
    for(int i=0; i<size; i++){
        printf("%.1lf ", array[i]);
    }
    putchar('\n');
}

int main(void){
    int size = 5;
    double *array = malloc(size * sizeof(double)); 
    double temperature;
    int i = 0;

    while(1){
        if(temperature == -100.0)
            break;
        if(i == size){
            size *= 2;
            array = realloc(array, size * sizeof(double));
        }
        scanf("%lf", &temperature);
        array[i] = temperature;
        printArray(array, size);
        i++;
    }
    free(array);
    return 0;
}

Upvotes: 2

0___________
0___________

Reputation: 67751

#define INITIALSIZE 5

typedef struct 
{
    size_t size;
    size_t index;
    int data[];
}DATA_t;

DATA_t *addData(DATA_t *data, int val)
{
    if(!data)
    {
        data = malloc(INITIALSIZE * sizeof(data -> data[0]) + sizeof(*data));
        /* malloc result checks */
        data -> size = 0;
        data -> index = 0;
    }
    if((data -> index + 1) == data -> size)
    {
        size_t newsize = data -> size * 2 ;
        DATA_t *newdata = malloc(newsize * sizeof(data -> data[0]) + sizeof(*data));
        /* malloc result checks */
        memcpy(newdata, data, data -> size * sizeof(data -> data[0]) + sizeof(*data));
        newdata -> size = newsize;
        free(data);
        data = newdata;
    }
    data -> data[data -> index++] = val;
    return data;
}

usage:

DATA_t *mydata = NULL;

while(condition)
{
    mydata = addData(mydata, ReadValue());
    /* ----- */
}

Upvotes: 0

Related Questions