-1

I want to try to create a C program which lets the user determine the array size of global variables (to make my program more dynamic). But there's a catch because you can't use scanf outside the scope. Can you guys help me with this?

I've tried using scanf outside the scope and it's not possible.

This is the code that works (the user can't determine the array size of the global variables):

#include <stdio.h>

int arr[100];
int tempArr[100];

void merge(int left, int middle, int right){
    int leftIndex, rightIndex, index;
    for(leftIndex = left, rightIndex = middle + 1, index = left;leftIndex<=middle && rightIndex<=right;index++){<br>
        if(arr[leftIndex]<arr[rightIndex]){
            tempArr[index] = arr[leftIndex++];
        }else{
            tempArr[index] = arr[rightIndex++];
        }
    }
    while(leftIndex<=middle){
        tempArr[index++]=arr[leftIndex++];
    }
    while(rightIndex<=right){
        tempArr[index++]=arr[rightIndex++];
    }
    for(int j = left; j<=right; j++){
        arr[j]=tempArr[j];
    }
}

void sort(int left, int right){
    int middle =0;
    if(left<right){
        middle=(left+right)/2;
        sort(left, middle);
        sort(middle+1, right);
        merge(left,middle,right);
    }
}

int binarySearch(int arr[], int left, int right, int search){
    int middle = 0;
    if(left<right){
        middle = (left+right)/2;
        if(arr[middle]==search){
            return middle;
        }else if(arr[middle]>search){
            return binarySearch(arr,left,middle,search);
        }else{
            return binarySearch(arr,middle+1,right,search);
        }
    }
    return -1;
}

int main(){
    int search;
    int index = 0;
    int arraySize = 0;
    scanf("%d", &arraySize); getchar();
    for(int i=0;i<arraySize; i++){
        int number;
        scanf("%d", &number); getchar();
        arr[index] = number;
        index++;
    }

    printf("Before sorting\n");
    int size=sizeof(arr)/sizeof(arr[0])-1;

    for(int i =0;i<=arraySize;i++){
        if(arr[i]!=0){
            printf("%d %d\n",arr[i],i);
        }
    }

    sort(0, arraySize-1);

    printf("\nAfter sorting\n");
    for(int i =0;i<=arraySize;i++){
        if(arr[i]!=0){
            printf("%d %d\n",arr[i],i);
        }
    }   

    printf("\nSearch a number: ");
    scanf("%d",&search);
    int result = 0;
    result = binarySearch(arr,0,arraySize,search);
    printf("Result: %d",result);
    return 0;
}

And I tried these few lines below and they didn't work. I'm not sure if there is another way I can think of.

#include <stdio.h>

int slot;
scanf("%d",&slot);
int arr[slot];
int tempArr[slot];
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Elmer Matthew
  • 17
  • 1
  • 4
  • 1
    One word for you: `malloc`. – Steve Summit Sep 03 '19 at 10:11
  • I have quite a little bit of understanding on how to implement ```malloc```. Perhaps, a quick tutorial would be helpful. Thanks for the quick reply. – Elmer Matthew Sep 03 '19 at 10:14
  • @ElmerMatthew Please do not try to implement `malloc` yourself. It isn't worth it. – S.S. Anne Sep 03 '19 at 11:26
  • Do you mean "determine" in the sense of "choose", or in the sense of "find out"? – John Bollinger Sep 03 '19 at 11:53
  • 2
    @JL2210 I assume he meant "how to use `malloc`". Elmer: There are zillions of tutorials on how to do this (and, by now, a couple of answers here to your question). I'd try a web search for "C malloc dynamic array" or something like that. – Steve Summit Sep 03 '19 at 11:53
  • 1
    And if the point is to create a flexible, reusable library, then have you considered how problematic global variables are for such purposes? – John Bollinger Sep 03 '19 at 11:57
  • 1
    @JohnBollinger One step at a time, I'd say. Before worrying about global variables, I'd worry about asking the user to explicitly prespecify something that the program arguably ought to figure out for itself, truly dynamically. – Steve Summit Sep 03 '19 at 12:06

3 Answers3

1

How to let user determine array size of global variables?

Users don't determine sizes of variables, programmers do. It might for example make perfect sense to set a static, maximum allowed size and then one valid use-case could be to only use part of the array.

In case you need to set the size of an array in run-time, you use dynamic allocation with malloc. Study dynamic allocation. And that's it.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

The original code is:

#include <stdio.h>

int slot;
scanf("%d",&slot);
int arr[slot];
int tempArr[slot];

The modified code is:

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

int slot;
scanf("%d",&slot);
int *arr=malloc(sizeof *arr *slot);
int *tempArr=malloc(sizeof *tempArr *slot);

Here is an example about "let user determine array size of global variables".

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

// [1]. use "pointer" instead of "array" 
int *arr;
int size=0;

void init(void)
{
    int i;
    for(i=0;i<size;i++)
    {
        arr[i]=i;
    }
}

void display(void)
{
    int i;
    for(i=0;i<size;i++)
    {
        printf("%d, ",arr[i]);
    }
    printf("\n");
}

int main(void)
{
    if(scanf("%d",&size)==-1)
    {
        return 0;
    }

    //[2]. use "malloc" to request variable size of memory
    //     "malloc" require <stdlib.h>
    arr=malloc(sizeof *arr *size);
    if(arr==NULL)
    {
        return 0;
    }

    //init and display
    init();
    display();

    //[3]. releasing the memory space is a good habit.
    free(arr);

    return 0;
}
  • 3
    [Please don't cast the return value of `malloc()`](https://stackoverflow.com/a/605858/28169). – unwind Sep 03 '19 at 10:49
  • Please include the details of what you changed outside of the code. – S.S. Anne Sep 03 '19 at 11:25
  • 2
    This is a code only answer which is a bad thing. Elaborate and explain rather than just giving code examples. Furthermore, this answer is teaching bad habits. – klutt Sep 03 '19 at 12:32
  • 2
    @klutt, It's almost like a checklist of how not to write C: ignoring the result of `scanf()`, casting the result of `malloc()`, not checking for failed `malloc()`, variables with meaningless names declared with greater scope than necessary, non-prototype `main()` instead of `main(void)`. – Toby Speight Sep 03 '19 at 13:04
  • 1
    Not casting the result of malloc = beating the dead horse. We've had C99 since... 99. It's been 20 years since the malloc cast+missing stdlib include bug went obsolete. The cast is fairly pointless but also harmless nowadays. As for ignoring the result of scanf... the main mistake is the use of stdio.h in the first place. It is a buggy, dangerous mess that shouldn't be used in production code. Main purpose of the lib is to for learning C in an academic environment, where things like buffer overflows are of peripheral interest. – Lundin Sep 04 '19 at 06:29
0

Arrays declared "globally" (at file scope) cannot have their sizes set at runtime. Their sizes must be specified with a constant expression that can be evaluated at compile time (such as a numeric literal or a sizeof operation on another object).

Objects with static storage duration (globals and anything declared with the static keyword) are loaded into memory as soon as the program starts, well before you prompt the user for any input, and their sizes have to be known immediately.

So, if you want a "global" array whose size isn't known until runtime, you'll have to use malloc or calloc:

int *arr = NULL;
int *tmpArr = NULL;
...
int main( void )
{
  int arrsize = 0;
  ...
  scanf( "%d", &arrsize ); // ideally want to check that scanf succeeded.

  arr = malloc( sizeof *arr * arrsize );
  if ( !arr )
  {
    // malloc failed, probably want to exit here
  }
  tempArr = malloc( sizeof *tempArr * arrsize );
  if ( !tempArr )
  {
    // same as above
  }

  ...

When you're done, you release the memory with free before exiting the program:

  ...

  free( arr );
  free( tempArr );

  exit( EXIT_SUCCESS );
}
John Bode
  • 119,563
  • 19
  • 122
  • 198