scanf infinite loop - c

This program takes the first number in a file and indicates how many numbers are going to be after it, then does various other things with the numbers that follow.
It seems like scanf is causing an infinite loop when trying to read from the file. WHen I run the program not even the check at 1 works
Here is the code:
#include <stdio.h>
int main(void) {
int N, a, n;
int x=0;
int t=0;
printf("1"); //Check
scanf("%d", &N);
printf("2"); //Check
int nums[N];
int i;
printf("%d", &N); //Check
for (i=0; i<N; i++)
{
scanf("%d", &nums[i]);
t+=nums[i];
if (nums[i] > x) x=nums[i];
if (i=0 || nums[i] < n) n = nums[i];
}
a = t/N;
printf("Number Processed: \t%d\n", &N);
printf("Maximum: \t%d\n", &x);
printf("Minimum: \t%d\n", &n);
printf("Total: \t%d\n", &t);
printf("Average: \t%d\n", &a);
}
The way i run the program is
gcc -lab16
./a.out <in1
where in1 is text and has the numbers
7
6
-30
90
3903
-934
443
445
Thanks for your time.

if (i=0 || nums[i] < n) n = nums[i];
you are assigning i = 0, so the loop never realy advances! You probably wanted i == 0. This is causing the infinite loop.
Other issue: int nums[N]; - if you want an array of dynamic [determined in run-time] size, you will probably need to malloc() it.
Update: note that int nums[N] is valid in C99, so if your assigment is assuming C99 you should not worry about this issue. Otherwise - malloc() will be needed:
int* nums = (int*) malloc(sizeof(int) * N)
And don't forget to free(nums) before the program ends, or you will get memory leak.

if (i=0 || nums[i] < n) n = nums[i];
This is the culprit. You are making an assignment i=0 when you should do a comparison : i==0
Your loop goes to infinity because everytime you are i to 0.
Moreover, the code you gave us, gave me an error, because you were creating new variables during runtime.
#include <stdio.h>
#include "stdlib.h"
int main(void) {
int N, a, n;
int x=0;
int t=0;
int i;
int *nums;
printf("1"); //Check
scanf("%d", &N);
printf("2"); //Check
nums = malloc(N*sizeof(int));
....

There are numerous problems with this code.
You mistook assignment for comparison:
i=0
sets i to zero. You probably meant
i==0
which checks whether i is equal to zero.
You should check the value returned by scanf(). When data read by scanf() doesn't fit the format you specified it leaves the data in the buffer and the next call to scanf() sees the same data again.
The reason that the first printf() doesn't print anything is most likely that you are not printing any newline. Note that on some output devices like terminals output is line-buffered.
You are passing a pointer to a variable to printf(), but your format specifies %d. You probably meant the variable itself, not a pointer to it.
Also, if you need an array of length dependent on a value known only at runtime, you need to allocate it on the heap, e.g. using malloc().

Related

How to work with a variable number of variables in C?

So I was pondering about this problem in C using only stdio.h -
I have to write a program that reads an integer p and then reads p integers. Now I have to use these p integers and perform another operation on them to get a final answer, which my main program will return.
The problem is I don't know how to perform an operation on a variable number of integers. I tried using pointers but they don't seem to work.
Can anyone help please?
#include <stdio.h>
int main(){
int i, p, n;
scanf ("%d", &p);
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++){
int a=*k;
if (a==0)
i=0;
else i=1;
}
return i;
}
What I want to do here is to read a certain integer p, then read p integers a, and if at least one of these as is 0, my answer is 0. Otherwise it's 1.
But the compiler says *k is not defined for the second for loop. What should I do?
I think you can do this with a fixed number of variables. Like
int p, a, ans=1;
scanf("%d", &p); //read number
for(int r=0; r<p; ++r)
{
scanf("%d", &a);
if(a==0)
{
ans=0;
break;
}
}
printf("\nAnswer is: %d", ans);
ans variable holds the answer. First you read the number of ints into p and then read p number of ints using a loop.
During each iteration of the loop, you read into the same variable a. You just need to know if at least a single input is zero.
ans is initially set to 1 and is changed to 0 only if a zero is input. If zero is input, the control exits the loop immediately because of the break statement.
You may want to check the return value of scanf() and other error checking.
Various ways to use an unknown number of variables is mentioned in the comments.
If you can use C99, variable length array are allowed. Like
int p;
scanf("%d", &p);
int arr[p];
If dynamic memory allocation is used, you could use malloc() or calloc() which are in stdlib.h.
See this.
And the pointer k in
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++){
int a=*k;
if (a==0)
i=0;
else i=1;
}
is a local variable of the first loop and is hence visible only to that loop and is invisible to the second loop. k's scope is limited to the first loop. See this.
If you want a variable to be visible in both the loops, declare it outside both.
First things first, I'll help you understand the compiler error you talked about:
k is not defined for the second for loop
// some code
for (n=0; n<p; n++){
int a;
scanf ("%d", &a);
int *k=&a; // Definition of k is here, and is restricted to this block,
}
for (n=0; n<p; n++){
int a=*k; // Its undefined here
if (a==0)
i=0;
else i=1;
}
// some code
Explanation: Read the comment in the code. What I meant by block is the code between the upper '{' and lower '}'. Beyond these, anywhere in code, k is undefined. Hence in second loop, the k is undefined.
You should change your main() function to:
int main()
{
int i, p, n, k = 0;
scanf ("%d", &p);
for (n=0; n<p; n++) {
int a;
scanf ("%d", &a);
int *k=&a;
}
for (n=0; n<p; n++) {
int a=*k;
if (a==0)
i=0;
else
i=1;
}
return i;
}
Now to address your next issue, I guess you might want to study variadic functions in C. I may be wrong in understanding your problem statement, but my take on it is that you are willing to pass multiple arguments to a function. For example,
At some time, you want to call function as:
function(Count_args, 1, 2, 3, 4, 5);
and sometimes as:
function(Count_args, 10);
If I am right, you might want to take a look at this example on the same reference I cited above. For making your life easier, I am adding the same code here:
#include <stdarg.h>
#include <stdio.h>
int
add_em_up (int count,...)
{
va_list ap;
int i, sum;
va_start (ap, count); /* Initialize the argument list. */
sum = 0;
for (i = 0; i < count; i++)
sum += va_arg (ap, int); /* Get the next argument value. */
va_end (ap); /* Clean up. */
return sum;
}
int
main (void)
{
/* This call prints 16. */
printf ("%d\n", add_em_up (3, 5, 5, 6));
/* This call prints 55. */
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
return 0;
}
If you are willing to know that latest standard says about having variable arguments to a function, refer C11, section 7.16 Variable arguments , it does help!

How to use variable length array in gcc?

So, I've read on this site that c++ doesn't allow variable length array but gcc allows it. So, I wanted to test a small code
#include<stdio.h>
#include<stdint.h>
void main()
{
int8_t n;
int8_t var_array[n];
int8_t i;
printf("Enter array size: \r\n");
scanf("%d", &n);
for(i=0; i<n; i++)
var_array[i] = i;
for(i=0; i<n; i++)
printf("var_array[%d] = %d\r\n", i, var_array[i]);
}
The code compiles with "gcc var_array.c -o var_array" command in linux OS but when I run it, I get segmentation fault error
Enter array size:
5
Segmentation fault
What am I doing wrong?
Also make it int, as you are using %d specifier. (because earlier will only be of 8 bits which might overflow in case of large values)
int n;
int i;
printf("Enter array size: \r\n");
if( scanf("%d", &n) != 1 ){
fprintf(stderr,"%s\n","Error in input");
exit(1);
}
int var_array[n];
for(i=0; i<n; i++)
var_array[i] = i;
...
You were using an unintialized variable. And then based on new valu eof n accessing the array. The indices most probably indexed out of the bound of the array giving you seg fault.
For inputting int8_t use scanf("%" SCNd8, &n);. You can also input the int8_t type.
Yes scanf's return value must be checked.
So the ideal call would be
if( scanf("%d",&n) == 1 ){
//...success..do work
}
The Mistake in the program is
int8_t n; //Here n is declared where n has random value
int8_t var_array[n]; /*Now in this statement you have declared array
with the size of that random value*/
So You get that error,In order to rectify that you have to get the input value of n and then you declare the var_array[n]

Scanf in to array

This a dot_product function of 2 vectors of the same length.
I don't understand how to build the array because how the machine will know which input goes to which input (for example i want a={1,2,3} but the input of 123 will come a[0]= 123)...
How do I make end of array[index] input and how do I make end of the whole array.
#include <stdio.h>
#include <stdlib.h>
#define MAXINPUT 100
int dot_product(int v[], int u[], int n)
{
int result = 0;
int i;
for (i=0; i < n; i++)
result += v[i]*u[i];
return result;
}
int main(){
int v1[MAXINPUT];
int v2[MAXINPUT];
int count = 0
int i,print;
printf(" first vector:");
for(i=0;i<MAXINPUT;i++){
scanf("%d", &v1[i]);
count +=1;
}
printf(" second vector:");
for(i=0;i<MAXINPUT;i++)
scanf("%d", &v2[i]);
print = dot_product(v1, v2, count);
printf("v1*v2:%d",print);
return 0;
}
The first problem I observe here is with
count +=1;
where count is an uninitialized automatic local variable, which makes it's initial value indeterminate. Attempt to use that value invokes undefined behavior.
You should be initializing count to 0.
That said, here, you're depending on the user to input the second array with exact same dimension of that of the first one. In case that does not happen, your program will blow up, as you did not initialize the arrays, again.

Scan and sum using array in C

I'm trying to write a simple program that'll prompt the user to enter N numbers, store them in an array, then just sum them all up
I understand I can just do this with a recursion but I'm trying to learn how array works
Example:
1 (hit enter)
2 (hit enter)
...
10 (hit enter)
Expected output: 55
#include <stdio.h>
int main (void){
int n;
int a[n];
int counter;
printf("How many numbers do you want to enter? \n");
scanf("%d", &n);
printf("OK! now enter your number: \n");
for (int i = 0; i <= n; i++){
scanf("%d", &a[i]);
counter =+ a[i];
}
printf("The answer is: %d\n", counter);
return 0;
}
Right now there's no error message, no output, just the standard windows error message
"scanner.exe has stopped working..."
I'm using Win8 and GCC compiler
First of all, you can't create an static array without first knowing its size. You first need to ask the user for the "n" variable and then declare your array.
You also need to explicitly initialize your counter variable to be zero before you start counting. In C, variables don't default to 0 when you declare them.
The operator "=+" doesn't exist AKAIK, change it to "+=".
Last but not least, the limit in your loops is a little off, you're asking for 11 values ;)
(I edited this post, I was wrong about only asking for 9 values. I tend to confuse that sort of stuff)
#include <stdio.h>
int main (void){
int n;
int counter = 0;
printf("How many numbers do you want to enter? \n");
scanf("%d", &n);
int a[n];
printf("OK! now enter your number: \n");
for (int i = 0; i < n; i++){
scanf("%d", &a[i]);
counter += a[i];
}
printf("The answer is: %d\n", counter);
return 0;
}
You are using variable length arrays. At run time the value of n must be known. Place the declaration
int a[n];
after taking input for n, i.e, after scanf("%d", &n); and initialize counter to zero before using it otherwise you will get garbage value (because of undefined behavior).
Also change the for loop condition from i <= n to i < n.
After this line:
int n;
What do you think the value of n is?
Now go to the next line:
int a[n];
How big is this array?
Can you access it properly?

My program crashes, I don't understand why it does not even reach the first printf

My program is supposed to order a list of numbers inputed by the user, but it crashes even before reaching the first printf. My compiler makes 2 warnings, but I don't see the issue. I haven't studied pointers yet, so I didn't want to use them. Here are the messages:
In function `selection_sort':
[Warning] passing arg 2 of `selection_sort' makes pointer from integer without a cast
In function `main':
[Warning] passing arg 2 of `selection_sort' makes pointer from integer without a cast
.
#include<stdio.h>
int selection_sort(int n, int v[n])
{
int high = v[0];
int i;
for(i = 0; i < n; i++)
high = high < v[i]? v[i] : high;
if(n - 1 == 0)
return;
v[n - 1] = high;
n -= 1;
selection_sort(n, v[n]);
}
int main(void)
{
int n, i;
int v[n];
printf("Enter how many numbers are to be sorted: ");
scanf("%d", &n);
printf("Enter numbers to be sorted: ");
for(i = 0; i < n; i++)
scanf("%d", &v[i]);
selection_sort(n, v[n]);
printf("In crescent order: ");
for(i = 0; i < n; i++)
printf("%d ", v[i]);
getch();
return 0;
}
Your program is using a variable length array, a feature that was added in C99.
However, you declare its size based on an uninitialized variable. What did you believe would happen there?
In C, variables declared inside functions are NOT set to 0. They are not set to anything. They pick up whatever value was left on the stack or in the register that they are assigned.
I believe that your program is crashing because n in int v[n] is a ridiculously big number and v is trying to use too much memory.
You can probably fix this by moving your array declaration below the scanf that reads in n.
You need to pass v, not v[n] to the function selection_sort. v is the array, v[n] is actually an out of bounds element of v.
the line should be selection_sort(n, v);

Resources