How to take array size of length as user input? - c

I would like to improve my program with user-input of array length. Is that possible in C?
This my code:
int main() {
int sum = 0;
int a;
int array[a] = {};
printf("Insert length of array:\n");
scanf("%d", &a);
for (int i = 0; i < a; i++) {
printf("Insert number %d \n", i + 1);
scanf("%d", &array[i]);
}
for (int i = 0; i < a; i++) {
sum = sum + array[i];
}
printf("Sum is %d \n", sum);
return 0;
}
However when I try to compile it, it says: error: variable-sized object may not be initialized
Any possible solution?

Yeah, in C you couldn't create variable-sized array, and variable-sized in this context means that you can't create array when it's size isn't constant on the compile time. But you can use pointers, and after user input you can allocate array with the appropriate length.
For example:
int* array;
int length;
printf("Enter length of the array: ");
scanf("%d", &length);
// maybe you need to add checking, like if length > 0
array = malloc(sizeof(int) * length);
// now you have array with `length` elements and 0..`length`-1 indexes

There are multiple reasons for your program to fail:
the definition int array[a] = {}; uses an uninitialized variable a, so the program has undefined behavior. You must define this array after reading the value of a.
variable sized automatic arrays cannot have an initializer. You must initialize the array some other way, or not at all since you read the values in the following loop.
if the size a is negative or too large, the creation of the local array will have undefined behavior. Allocating from the heap with malloc() or calloc() is preferable for potentially large objects.
you do not test the return value of scanf(), causing undefined behavior on invalid input.
Here is a corrected version:
#include <stdio.h>
int main() {
int sum;
int a;
printf("Insert length of array:\n");
if (scanf("%d", &a) != 1 || a <= 0 || a > 1000) {
fprintf(stderr, "Invalid input\n");
return 1;
}
int array[a];
for (int i = 0; i < a; i++) {
printf("Insert number %d:\n", i + 1);
if (scanf("%d", &array[i]) != 1) {
fprintf(stderr, "Invalid input\n");
return 1;
}
}
sum = 0;
for (int i = 0; i < a; i++) {
sum = sum + array[i];
}
printf("Sum is %d\n", sum);
return 0;
}
If you want to handle larger arrays, you can allocate the array with malloc(), but you can also just compute the sum on the fly and not store the values read in an array:
#include <stdio.h>
int main() {
int a, value, sum;
printf("Insert length of array:\n");
if (scanf("%d", &a) != 1 || a < 0) {
fprintf(stderr, "Invalid input\n");
return 1;
}
sum = 0;
for (int i = 0; i < a; i++) {
printf("Insert number %d:\n", i + 1);
if (scanf("%d", &value) != 1) {
fprintf(stderr, "Invalid input\n");
return 1;
}
sum += value;
}
printf("Sum is %d\n", sum);
return 0;
}

Related

C Program returns garbage value for avg

When running this program using pointers and arrays to calculate the grade point average from the user input, it outputs a garbage value. How can I alter the code so that the output is correct?
void Insert_Grades(int *array)
{
int grades[4];
int i;
for (int i = 0; i < 4; i++)
{
printf("Enter grade %d: ", i + 1);
scanf("%d", &grades[i]);
}
array = grades;
}
void Calculate_Avg(int *array)
{
int i;
float avg;
float sum = 0;
for (i = 0; i < 4; i++)
{
sum += *(array + i);
}
avg = sum / 4;
printf( "Grade point average is: %f ", avg);
}
int main()
{
int grades[4];
int i;
printf("Enter the number of grades:\n");
Insert_Grades(grades);
Calculate_Avg(grades);
printf("\n");
return 0;
}
you cant assign arrays.
This operation assigns local pointer array with reference of the local array grades. For the extral world this operation means nothing.
array = grades;
You need to copy values instead.
memcpy(array, grades, sizeof(grades));
or
for (size_t index = 0; index < 4; index++)
array[index] = grades[index];
There are multiple problem in your code:
in function Insert_Grades, value are read into the local array grades. The last instruction array = grades has no effect because it only modifies the argument value, which is just local variable, a pointer to int that now points to the first element of grade array.
This explains why the program outputs garbage because the array grades defined in the main() function is uninitialized and is not modified by Insert_Grades().
You could copy the array grade to the caller array pointed to by array, but it seems much simpler to use the array pointer to read the values directly where they belong.
the variable i is defined multiple times, with nested scopes.
you should test the return value of scanf() to detect invalid or missing input.
Here is a modified version:
#include <stdio.h>
void Insert_Grades(int *array, int count) {
for (int i = 0; i < count; i++) {
printf("Enter grade %d: ", i + 1);
if (scanf("%d", &array[i]) != 1) {
fprintf(stderr, "invalid input\n");
exit(1);
}
}
}
float Calculate_Avg(const int *array, int count) {
float sum = 0;
for (int i = 0; i < count; i++) {
sum += array[i];
}
return sum / count;
}
int main() {
int grades[4];
int count = sizeof(grades) / sizeof(*grades);
float avg;
printf("Enter the grades:\n");
Insert_Grades(grades, count);
avg = Calculate_Avg(grades, count);
printf("Grade point average is: %.3f\n", avg);
return 0;
}

Finding a number ( to be read from keyboard) in the list , where the size of list and the list is to be read from the keyboard

I am not able to figure out the error in the following code where I want to check a number in the list, the code prints yes, if it's present, and no if not. The output that I receive is random yes and no. Sometimes it's correct but other times, it's wrong.
{
int n, N, a[n], i, flag = 0;
printf("n , N\n");
scanf("%d%d", &n, &N);
printf("a\n");
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n; i++)
{
if(a[i] == N)
{
flag = 1;
break;
}
}
if(flag == 0)
printf("No\n");
else
printf("Yes\n");
return 0;
}
I am trying to take an array with size n, which the user will input afterwards in the code and simultaneously while declaring the size I am entering the value of N, which is to be found in the list .. then using for loop I am comparing every number stored, but I think here the code fails.
The problem statement says you need to find out whether the value given as N exists among the n values given. It does not require you to store those n values.
So it's enough to check each of them as soon as it arrives and ...abandon it, memorizing just a positive result of test. No array needed.
Here is a simplified implementation:
int n, N, a, i, flag = 0;
puts("n , N");
scanf("%d%d", &n, &N);
puts("a");
for(i = 0; i < n; i++) {
scanf("%d", &a);
if(a == N)
flag = 1;
}
puts(flag ? "Yes" : "No");
At first, try to understand what 'some programmer dude' commented on your post. There is a bug in your code. You declared the array a[n], while the variable n is not initialized yet. So at first, you need to declare a pointer *a, then take the size of the array as an input from the user, and then finally allocate memory in pointer *a with the malloc() function. So here is the working code:
#include<stdio.h>
#include <stdlib.h>
int main()
{
int n, N, *a, i, flag = 0;
printf("n , N\n");
scanf("%d%d", &n, &N);
a = (int *) malloc(sizeof(int) * n);
printf("a\n");
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n; i++)
{
if(a[i] == N)
{
flag = 1;
break;
}
}
free(a);
if(flag == 0)
printf("No\n");
else
printf("Yes\n");
return 0;
}

build error in code block for function gets

I want to make a simple variable for number of the round for a loop, so I tried my code
int size,counter,marks[size];
scanf("enter %d/n",&size);
for(counter=0;counter<size;counter++)
{
scanf("%d",&marks[counter]);
}
and compiled with no error but in run, it just shows "process returned -1073741571 <0*c00000FD>.
so I tried gets function and it shows "too many arguments to function 'gets' ".
int size;
int counter;
int marks[size];
scanf("enter %d/n",&size);
for(counter=0;counter<size;counter++)
{
gets("%d",&marks[counter]);
}
I'm using code::blocks 17.12 and the gnu compiler.
size can have any value when the array marks is allocated because it is not initialized. The array might be smaller than the entered size and so marks are stored in non-allocated memory, giving you the error.
This is a possible solution, but it doesn't compile with strict ISO C90. Presumably your CodeBlocks uses GCC that accepts variable length arrays and mixed declarations and code.
#include <stdio.h>
int main(void) {
int size;
printf("enter size: ");
scanf("%d",&size);
int marks[size];
int counter;
for (counter = 0; counter < size; counter++) {
scanf("%d", &marks[counter]);
}
for (counter = 0; counter < size; counter++) {
printf("%d: %d\n", counter, marks[counter]);
}
return 0;
}
BTW, please don't say "build error" if you have a runtime error. ;-)
Please don't use gets. It's dangerous.
As for your error in the scanf example, the first problem is the line
int size,counter,marks[size];
which declares marks with the uninitialized size value. Try initializing size first, then declaring the marks array.
Your second problem is scanf formatting string. Use scanf to read formatted input, not output a prompt. Use puts or printf for that.
Here's a full example:
#include <stdio.h>
int main(void) {
int size;
printf("Enter a size value: ");
scanf("%d", &size);
int marks[size];
for (int i = 0; i < size; i++) {
printf("Enter element %d: ", i);
scanf("%d", &marks[i]);
}
printf("You entered: ");
for (int i = 0; i < size; i++) {
printf("%d ", marks[i]);
}
puts("");
return 0;
}
Here's a sample run:
Enter a size value: 4
Enter element 0: 88
Enter element 1: 77
Enter element 2: 66
Enter element 3: 55
You entered: 88 77 66 55
If you're writing ANSI C-compatible code you can use dynamic memory with malloc:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, size, *marks;
printf("Enter a size value: ");
scanf("%d", &size);
if (size < 1) {
fprintf(stderr, "Invalid size specified\n");
exit(1);
}
marks = malloc(size * sizeof(int));
if (!marks) {
fprintf(stderr, "malloc failed\n");
exit(1);
}
for (i = 0; i < size; i++) {
printf("Enter element %d: ", i);
scanf("%d", &marks[i]);
}
printf("You entered: ");
for (i = 0; i < size; i++) {
printf("%d ", marks[i]);
}
free(marks);
puts("");
return 0;
}
size must have a defined value, for example:
#include <stdio.h>
int main()
{
int size;
size = 5; // size must be constant
int counter, marks[size];
for (counter = 0; counter < size; counter++)
{
scanf("%d", &marks[counter]);
}
//Printing it returns correct values:
for (counter = 0; counter < size; counter++)
{
printf("%d\n", marks[counter]);
}
}
You can instead input it's value from the user if you want.
However, if for some reason, size is to be defined after the array is declared, use pointers:
#include <stdio.h>
#include "stdlib.h"
int main()
{
int size;
int counter, *marks;
size = 5; //declared after the array
marks = (int *)malloc(size * sizeof(int));
for (counter = 0; counter < size; counter++)
{
scanf("%d", &marks[counter]);
}
//Printing it returns correct values:
for (counter = 0; counter < size; counter++)
{
printf("%d\n", marks[counter]);
}
//Don't forget to free the array in the end
free(marks);
}

While loop with user input validation to fill array, then search array for largest number.

I am working on a program that will accept user input to fill an array and then quit when the user enters q. Next the array is passed to a function that finds the largest value in the array. My program seems like it would work, but I believe that user input for the array is incorrect and I am not sure how to solve it.
#include <stdio.h>
#define SIZE 30
int maxnum(int userarray[], int maxx);
int main()
{
int i;
int nums[SIZE];
int largest;
printf("Type integer numbers (up to 30), followed by q to quit:\n");
while(scanf("%d", &nums[i]) == 1)
{
for(i = 0; i < SIZE; i++)
{
//blank
}
}
largest = maxnum(nums, SIZE);
printf("The largest number is: %d\n", largest);
return 0;
}
int maxnum(int userarray[], int maxx)
{
int i;
int maxnumber;
maxnumber = userarray[0];
for(i = 1; i < maxx; i++)
{
if(maxnumber < userarray[i])
{
maxnumber = userarray[i];
}
}
return maxnumber;
}
First i is unitialized.
Then your inner for loop is strange (why someone would do that??) and sets i to SIZE in the end, which is not good.
I don't give more details, but the value of i is trash all the time because of those 2 mistakes it should be:
int i = 0;
while((i<SIZE) && (scanf("%d", &nums[i]) == 1))
{
i++;
}
so you read one by one, and protect against array out of bounds by the second condition.
After that you're passing NUMS
largest = maxnum(nums, SIZE);
whereas the array could contain fewer valid values. Just pass
largest = maxnum(nums, i);
Here is another solution for your problem.
In main() function
int n,i=0;
while(scanf("%d",&n) == 1){
nums[i++] = n;
}
n = maxnum(nums, i);
printf("The largest number is: %d\n", n);
Note : Initialize the value of i=0, Then input and update nums[] array
In maxnum() function
for(i = 0; i < maxx; i++) {
if(maxnumber < userarray[i]){
maxnumber = userarray[i];
}
}
Note: Start i=0 and find the max mumber and return the value

I'm trying to use the malloc function to allocate memory for an array but the the values aren't scanning in properly. Can anyone explain?

So I was asked to write a program that tests whether a sequence of integers input by the user is a palindrome or not (reads same backwards as forwards). I can't figure out how to dynamically allocate memory so that the input can be of variable length. In the code you can see that the user enters the number of elements in their sequence, n. But during compilation, when n integers have been entered nothing happens. What is wrong with the code? Please explain in detail as much as possible, and if you know of any good references share them!! I'm struggling with pointers and arrays.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i, n, x;
int* intarray;
printf("\nHow many integers are there?: \n");
scanf("d", &n);
intarray = (int*)malloc(n * sizeof(int));
printf("\nPlease enter the values:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &intarray[i]);
}
n = n - 1;
x = n / 2;
for (i = 0; i <= x; i++)
{
if (intarray[i] != intarray[n - i])
{
printf("\nThis is not a palindrome\n");
return;
}
if (i = x)
{
printf("\nThis is a palindrome\n");
}
}
return;
}
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i, n, x;
int* intarray;
printf("\nHow many integers are there?: \n");
scanf("%d", &n); // and as mentioned by all above type specifier % is missing in %d (for integer type)
intarray = (int*)malloc(n * sizeof(int));
printf("\nPlease enter the values:\n");
for (i = 0; i < n; i++)
{
scanf("%d", &intarray[i]);
}
n = n - 1;
x = n / 2;
for (i = 0; i <= x; i++)
{
if (intarray[i] != intarray[n - i])
{
printf("\nThis is not a palindrome\n");
return;
}
if (i = x)
{
printf("\nThis is a palindrome\n");
}
}
return 0; // as your main()'s return type is int, you should should return an integer value
}
The problem is with the scanf("d", &n); statement that actually does not read anything into n as in order to read an integer you should use "%d" instead of "d".
2 changes:
1.
scanf("%d", &n);
%d is the format specifier for scanning integers.
2.
intarray = malloc(n * sizeof(int));
No need to cast malloc()

Resources