User input array in C - c

Hello I am trying to make a program that lets the user input the size of the array.
I am stuck on making my array sized based on the user. This is what I have so far
void main(void)
{
const int size = 0;
int aval[size], i;
printf("Please enter the size of the array: ");
scanf("%i", &size);
printf("\n\nPlease enter array values:\n");
for (i = 0; i < size; i++)
{
scanf("%i", &aval[i]);
}
while (!_kbhit());
}

Better way would be:
int size = 0;
int *aval;
printf("Please enter the size of the array: ");
scanf("%i", &size);
/* Should verify size is reasonable here */
aval = malloc(size * sizeof(*aval));
printf("\n\nPlease enter array values:\n");
for (i = 0; i < size; i++)
{
scanf("%i", &aval[i]);
}
Doing it this way creates the array in the proper data area, rather than in the local automatic area, which may have limited size. Also, if you are done with the array before the end of the program, then you can free it to recover the space.

You initialize size with 0 and then create an array of the size of size, which is 0. Later size is changed, but that is not entangled to your array. Try this:
//Something before
const int size = 0;
printf("Please enter the size of the array: ");
scanf("%i", &size);
int aval[size], i;
//Something after

Related

Why I got this (Error (active) E0028 expression must have a constant value - line 23) for Array in C

/* In the space provided below, write a C code which asks a user how many numbers (up to 100) they want to enter.
The program then stores the data in an array and sends it to a function to compute the average of the numbers of the array.
The function should then return the average and the program should then print the average. */
#include<stdio.h>
float find_average(int *arr,int size){
float sum=0; // set sum to 0
// loop calculates the sum of values in the array
for(int i=0;i<size;i++){
sum+=arr[i];
}
//find average and return
float average=sum/size;
return average;
}
int main(){
int size; // int variable which stores the size of array
printf("Enter array size (up to 100): \n");
scanf("%d",&size); // user input of array size
int array[size]; // array initialization
printf("Enter the values into array:\n");
// user input of the array values
for(int i=0;i<size;i++)
{
scanf("%d",&array[i]);
}
float average=find_average(array,size); // calling find_average function by passing array and it's size
printf("The average of array values is: %.2f\n",average);
}
Why I got this (Error (active) E0028 expression must have a constant value) for Array in C. I'm using visual studio 2019.
I fixed your code: the array is given the fixed length of 100 and input given by the user is checked against that value. Note: this would deserve a #define instead of a hard coded constant. Another solution would have been to dynamically allocate the array according to the user input.
#include <stdio.h>
float find_average(int* arr, int size) {
float sum = 0; // set sum to 0
// loop calculates the sum of values in the array
for (int i = 0; i < size; i++) {
sum += arr[i];
}
//find average and return
float average = sum / size;
return average;
}
int main(void) {
int size; // int variable which stores the size of array
printf("Enter array size (up to 100): \n");
scanf("%d", &size); // user input of array size
if (size > 100) {
printf("I told you max 100!");
return;
}
int array[100]; // array storage
printf("Enter the values into array:\n");
// user input of the array values
for (int i = 0; i < size; i++)
{
scanf("%d", &array[i]);
}
float average = find_average(array, size); // calling find_average function by passing array and it's size
printf("The average of array values is: %.2f\n", average);
}
Use 100 (the maximum number of items specified) for the array size, and throw an error when the user asks for an array size bigger than that.
int size; // int variable which stores the size of array
do {
printf("Enter array size (up to 100): \n");
scanf("%d",&size); // user input of array size
if (size >= 100) {
printf("I told you up to 100, you entered %d\n", size);
}
} while (size >= 100);
int array[100]; // array initialization (100 elements despite we can use less)
// ^^^ this expression is what must be constant, not the contents of a variable.
printf("Enter the values into array:\n");
// ...

removing a range of elements from an array in c

I need to remove a range of elements from an array but I can't figure out how. I tried this for loop where start is the start of the range and end is the end of the range.
int main(void)
{
int n, n2, i, start, end, index;
int a1[n];
int a2[n2];
printf("Enter the length of the array#1: ");
scanf("%d", &n);
printf("Enter the elements of the array#1: ");
for (i = 0; i < n; i++){
scanf("%d", &a1[i]);}
printf("Enter the length of the array#2: ");
scanf("%d", &n2);
printf("Enter the elements of the array#2: ");
for (i = 0; i < n2; i++){
scanf("%d", &a2[i]);}
printf("Enter the start and end indexof array #1 to be removed: ");
scanf("%d %d", &start, &end);
int a3[(end-start)+1];
printf("Enter the position(index)of the array #2 to be added before: ");
scanf("%d", &index);
for (i=0;i < (n - end - 1);i++){
a1[start + i] = a1[end + i + 1];
a1[end + i + 1] = 0;
}
printf("\n");
printf("array1: ");
for (i=0;i < (n);i++){
printf("%d", a1[i]);
printf(" ");
}
You have:
Used n and n2 to give size of the array without initializing those variables first. Though you have not initialized your array but if you did, it would've failed due to VLA.
Not checked the input you are receiving from the user whether the range provided is feasible? What if end - start is greater than the length of the arrays.
Used 0 as a value to replace after that element has moved to a new location/index, what if the number being moved is 0 itself?
For the last point, use some value which has a very less probability of being entered by user like INT_MAX & you'll be needing limits.h header + after that it'll be good to make your for loop look like this:
for(index=0;((index<sizeArr)&&((arr[index]!=INT_MAX)));++index)
This loop will print start - end lesser values from the original array.
Since you want to determine the array size at runtime (via input from the user), you should be using dynamic allocation.
I'm not positive exactly what you are trying to accomplish with this script, but here's an example of what moving to dynamic allocation would look like:
int main(void)
{
int n, n2, i, start, end, index;
int *a1;
int *a2;
printf("Enter the length of the array#1: ");
scanf("%d", &n);
a1 = malloc(sizeof(int)*n);
printf("Enter the elements of the array#1: ");
for (i = 0; i < n; i++){
scanf("%d", &a1[i]);
}
printf("Enter the length of the array#2: ");
scanf("%d", &n2);
a2 = malloc(sizeof(int)*n2);
printf("Enter the elements of the array#2: ");
for (i = 0; i < n2; i++){
scanf("%d", &a2[i]);
}
You can access the values pointed to by a1 using normal array notation, but you should add some bounds checking to ensure the user does not specify an array index outside the bounds of n/n2.

Retaining input values in C?

I have asked for the user to enter in several values to calculate an average, however I'd like to also calculate a gradient which uses the inputted values. How do I name these values so I can use them again? Thank you.
Here is what I have thus far:
#include <stdio.h>
int main () {
int n, i;
float num[1000], total=0, mean;
printf("Enter the amount of x-values:");
scanf("%d", &n);
while (n <= 0 || n > 1000) {
printf("Print error. The number should in range of 0 to 1000.\n");
printf("Please try to enter the amount again: ");
scanf("%d", &n);
}
for (i = 0; i < n; ++i) {
printf("%d. Input x-value:", i+1);
scanf("%f", &num[i]);
total += num[i];
}
mean=total/n;
printf("The mean of all the x-values entered is %.2f to 2 decimal places", mean);
{
float num[1000], total=0, mean;
printf("Enter the amount of y-values:");
scanf("%d", &n);
while (n <= 0 || n > 1000) {
printf("Print error. The number should in range of 0 to 1000.\n");
printf("Please try to enter the amount again: ");
scanf("%d",&n);
}
for (i = 0; i < n; ++i) {
printf("%d. Input y-value:", i+1);
scanf("%f", &num[i]);
total += num[i];
}
mean = total / n;
printf("The mean of all the y-values entered is %.2f to 2 decimal places", mean);
return 0;
}
}
Naming the variable is really up to you, but `int gradient[NUM_ELEMENTS]; seems appropriate. It is an array, which also seems appropriate if it's purpose is to assist in finding the gradient from a series of numbers.
Steps could be:
1) use printf to ask user for values, specify spaces or commas between values. You can also specify a limit of values. Example printf("enter 5 numbers separated by commas\n:");
2) use scanf or similar to read values from standard input (the terminal) into the array: scanf("%d,%d,%d,%d,%d", &gradient[0], &gradient[1], &gradient[2], &gradient[3], &gradient[4]);
3) use the array an a function that will compute the gradient.
Simple example:
(where gradient computation, error checking, bounds checking etc. is all left to you)
int get_gradient(int a[5]);
int main(void) {
int gradient[5];
int iGradient=0;
printf("enter 5 numbers separated by commas");
scanf("%d,%d,%d,%d,%d", &gradient[0], &gradient[1], &gradient[2], &gradient[3], &gradient[4]);
iGradient = get_gradient(gradient);
return 0;
}
int get_gradient(int a[5])
{
return [do computation here using array a];
}
Edit:
The above example works only if you know the number of elements at compile time. It uses an int array that has been created on the stack. If you do not know how big of an array you will need until run-time, for example if user input determines the size, then the array size needs to be determined at run-time. One options is to create the variable needed on the heap. (read about stack and heap here) The following uses some techniques different from the simpler version above to get user input, including a function I called get_int(), which uses scanf() in conjunction with strtol(). Here's the example:
int main(void) {
char input[80]={0};
char **dummy={0};
long *gradient = {0};
int iGradient=0;
int arraysize;
int i;
char* fmt = "%[^\n]%*c";
printf("how many numbers will be entered?");
scanf(fmt, input);
arraysize = strtol(input, dummy, 10);
gradient = calloc(arraysize, sizeof(long));
if(gradient)
{
for(i=0;i<arraysize;i++)
{
gradient[i] = get_int();
}
iGradient = get_gradient(gradient, arraysize);
//free gradient when done getting result
free(gradient);
}
return 0;
}
int get_gradient(int *a, int num)
{
int grad = 0, i;
//do something here to compute gradient
return grad;
}
long get_int(void)
{
char input[80]={0};
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter integer number and hit return:\n");
scanf(fmt, input);
return strtol(input, dummy, 10);
}

Array of strings with no malloc in c

Can someone tell me whats wrong with that code?And i cant use malloc because i havent learn it in class.I mean can i make a 2d array of strings without malloc and if yes how i am i supposed to write an element when i want to change it/print it/scan it.Thanks in advance
int main() {
size_t x,y;
char *a[50][7];
for(x=0;x<=SIZEX;x++)
{
printf("\nPlease enter the name of the new user\n");
scanf(" %s",a[x][0]);
printf("Please enter the surname of the new user\n");
scanf(" %s",a[x][1]);
printf("Please enter the Identity Number of the new user\n");
scanf(" %s",a[x][2]);
printf("Please enter the year of birth of the new user\n");
scanf(" %s",a[x][3]);
printf("Please enter the username of the new user\n");
scanf(" %s",a[x][4]);
}
return 0;
}
So, you need a 2d array of strings (char arrays). One way to achieve this would be to allocate a 3d array of char as:
char x[50][7][MAX_LENGTH];
You can think as having a matrix of array start (of pointers) and then, another dimension to give depth to your matrix (i.e. storage space for your string).
Your approach is also fine, as long as you are willing to allocate manually using malloc or similar storage space for your strings.
can i make a 2d array of strings without malloc
Sure. Let's reduce this to 2*3:
#include <stdio.h>
char * pa[2][3] = {
{"a", "bb","ccc"},
{"dddd", "eeeee", "ffffff"}
};
int main(void)
{
for (size_t i = 0; i < 2; ++i)
{
for (size_t j = 0; j < 3; ++j)
{
printf("i=%zu, j=%zu: string='%s'\n", i, j, pa[i][j]);
}
}
}
Output:
i=0, j=0: string='a'
i=0 j=1: string='bb'
i=0, j=2: string='ccc'
i=1, j=0: string='dddd'
i=1, j=1: string='eeeee'
i=1, j=2: string='ffffff'

a C program crashes, using a double-type variable length array

I am reading C Primer Plus these days and here is the code I wrote for the programming practice No.4 in Chapter 10, finding the index of the largest number in a double-typed array. I used variable length array in order to manually specify the array size:
#include <stdio.h>
int findmax(const double array[], int s);
//find the index of the largest number in the array
int main(void)
{
int size = 0; //size of the array
int index = 0; //index of the largest number
double num[size]; //the array holding double-type numbers
printf("Enter the size of the array: ");
scanf("%d", &size);
printf("Enter %d numbers: ", size);
for (int i = 0; i < size; i++)
scanf("%lf", &num[i]);
index = findmax(num, size);
printf("The index of the max number in the array is: %d\n", index);
return 0;
}
int findmax(const double array[], int s)
{
int index = 0;
double max = array[0];
for (int i = 0; i < s; i++)
if (array[i] > max)
{
max = array[i];
index = i;
}
return index;
}
This piece of program compiles normally, using MinGW (assume the program file name is prog.c):
gcc prog.c -o prog.exe -std=c99
The program works fine when the "size" varialbe is less than 5. But when I enter 6 or larger numbers for the "size" varialbe, the program crashes during runtime.
Loosely translated, the error message is:
the memory 0x00000038 used by 0x77c1c192 could not be "written".
I tried to eliminate the use of variable length array, the program seems to work fine. But I still couldn't get where is wrong with the original one.
Size is 0 when you allocate num. You get access violation later on because you try to acces num[0] which has not been allocated.
EDIT: I propose to use dynamic memory or declare num after size is read.
Put the statment double num[size]; after taking input of size from user for size variable.
The program works fine when the "size" varialbe is less than 5. This is the most dangerous kind of programming error -- one that appears to work fine but really does not. By writing into your array, you're immediately writing into memory that is claimed for some other purpose, because your array has no length at all. You cannot just change the size of your array by changing the size variable after the fact.
One option is to determine size before you declare the array. Another is to perform a dynamic allocation using new, but you'll get into that in several chapters, I'm sure.
int size = 0; //size of the array
int index = 0; //index of the largest number
double num[size]; //the array holding double-type numbers
printf("Enter the size of the array: ");
scanf("%d", &size);
When you first declare num array, it's size would be zero, as this is the value of size when that line is executed, although you maybe reading the value of size again later on.
When you are creating an array, the size of the array will be zero as already pointed out by others. So, when you try to fill elements into the array, there is no memory available and it overwrites into some other memory eventually leading to a memory corruption.
You can rewrite the code as below to avoid the problem.
int size = 0; //size of the array
int index = 0; //index of the largest number
double *num = NULL; //Change it to a pointer
printf("Enter the size of the array: ");
scanf("%d", &size);
num = malloc(size * sizeof(double));
if(NULL == num)
{
printf("Malloc Failed\n");
return 0;
}
printf("Enter %d numbers: ", size);
for (int i = 0; i < size; i++)
scanf("%lf", &num[i]);
or
int size = 0; //size of the array
int index = 0; //index of the largest number
printf("Enter the size of the array: ");
scanf("%d", &size);
double num[size]; //Now, num will have proper size
printf("Enter %d numbers: ", size);
for (int i = 0; i < size; i++)
scanf("%lf", &num[i]);
Here's a link to an informative article about C99's variable length arrays which talks about some potential problems which C99's variable length arrays can cause.
As others have suggested, using malloc() is the correct way to do this. Other than that, you can just make your array an arbitrary large size, and stop accepting input once it's full.

Resources