Why this for loop ends in the second index? - c

I wrote a program that it's duty is to read 20 numbers from user and put them in a list, after that it prints the value in array from bottom to starting point.
But program stops exactly after reading second value from input.
Source code :
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i=0;i<N;i++)
{
scanf("%i", &numbers[i]);
}
for(i=N;i<0;i--)
{
printf("%i", numbers[i]);
}
return 0;
}
I use Dev-C++ 5.6.3 as my IDE and TDM-GCC 4.8.1 as my compiler. But I don't know exactly that is this an IDE related issue or not.

If you want the loop to count downwards, then this loop
for(i=N;i<0;i--)
starts at the wrong index, and fails the test condition. It should be
for(i = N - 1; i >= 0; i--)

If you want your second loop to count down, then
for(i=N;i<0;i--)
should be
for(i=N;i>0;i--)
or the loop will not execute, as i<0 is not true to start with.
and, as #WeatherVane pointed out in the comments:
scanf("%i", numbers[i]);
should be
scanf("%i", &numbers[i]);
as you need to pass a pointer to the integer you wish to fill in with the number that scanf returns.

There is some issue with the given below for loop.
for(i=N;i<0;i--)
{
printf("%i", numbers[i]);
}
return 0;
If you Want to print the array from bottom to starting point.
You can make some changes in the for loop.
Changes :
1- Change in loop while assigning the value to i :
i = N-1 -> as the size of array is 20 and array index starts with 0.
it will go 19 to 0 to print all 20 data values.
2- changes in the condition check in for loop :
i >= 0 as we printing the reverse array.
Correct for loop should be
for(i = N-1; i >= 0; i--)
{
printf("%i", numbers[i]);
}

for(i=N-1;i>=0;i--)
For n items in an array, last index will be n-1. you need to iterate from n-1 index to 0th index.

second loop must be
for(i=N;i>=0;i--)
so index will be from 19 to 0 ( 20 number )
Try This
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i = 0; i < N; i++)
{
scanf("%i", &numbers[i]);
}
for(i = N ; i >= 0; i--)
{
printf("%i ", numbers[i]);
}
return 0;
}

Try this:
#include <stdio.h>
#define N 20
int main(void)
{
int numbers[N];
int i;
for(i = 0; i < N; i++)
{
scanf("%i", &numbers[i]);
}
for(i = N - 1; i >= 0; i--)
{
printf("%i ", numbers[i]);
}
return 0;
}
Remember that scanf always uses pointers.

Your second loop's condition, "i<0", is false to begin with. It should be "i > -1". You also need to make sure that the first time printf is called with index 19 and not 20. That is why I use pre decrement operator -- i.
for(i = N; i > -1; )
{
printf("%i\n", numbers[--i])
};

Related

Why %d is showing 0 in my c program output?

The program is to find the largest number amongst all the entered integers. It asks the user to enter a number 10 times or press 0 to quit, whichever is earlier. But, the output is not as expected. I will appreciate it if you can help a newbie.
#include <stdio.h>
int main()
{
int num[10];
int max, a;
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
}
for(a = 0; a < 10; a++)
{
num[0] = max;
if(max < num[a])
{
num[a] = max;
}
}
printf("This is the largest integer: %d", max); //The output is coming wrong here.
return 0;
}
Don't use num[0], you are overwriting it with max variable which is not initialized, so it is 0.
Use max to the minimum type variable (INT_MIN with limits.h header file) or initalize it to max = num[0] after input is captured.
#include <limits.h>
int max = INT_MIN;
Also you need to change your second for loop as follows so as to update the max variable as you iterate, and not the num[] variables. Loop variable starts with 1 if you already assumed max to be first element before, else loop variable will start with 0.
for(a = 1; a < 10; a++) // a=0 if max was initialized to INT_MIN above
{
if(num[a]>max)
{
max = num[a];
}
}
You never assign the max variable.
What you want to do is to check if the value entered is greater than each one you've previously entered, so you would need to use the following condition:
if (num[a] > max)
max = num[a];
You also need to initialize max to some value (let's say, if you expect to have only positive integers, it could be 0, but have a look at Jigsaw answer for a better solution): int max = 0;.
And eventually add an if-condition that checks if max is 0, that way you know if no values have been entered:
if(max == 0)
printf("No values have been entered.");
else printf("This is the largest integer: %d", max);
Notice that you can assign the elements of num and update max in the same for loop, therefore the second for becomes completely useless and you can remove it:
#include <stdio.h>
int main()
{
int num[10];
int max = 0, a;
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
if (num[a] > max)
max = num[a];
}
if(max == 0)
printf("No values have been entered.");
else printf("This is the largest integer: %d", max);
return 0;
}
I suggest you to turn on your compilers warning, especially -Wall and -Wextra, so you would notice problems like these:
<source>: In function 'main':
<source>:17:16: warning: 'max' may be used uninitialized [-Wmaybe-uninitialized]
17 | num[0] = max;
| ~~~~~~~^~~~~
<source>:6:9: note: 'max' was declared here
6 | int max, a;
| ^~~
For starters this for loop
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
}
can enter less than 10 elements in the array num due to the condition
if (num[a] == 0)
break;
So the next loop has to traverse exactly a elements of the array not 10. So in the next loop you have to use another variable for the index as for example
for( int i = 0; i < a; i++)
The variable max was not initialized
int max, a;
So this for loop invokes undefined behavior where the variable max is assigned to elements of the array or where it is compared with elements of the array.
for(a = 0; a < 10; a++)
{
num[0] = max;
if(max < num[a])
{
num[a] = max;
}
}
Moreover the variable max is not changed within the for loop. So the loop in whole does not make sense.
Pay attention to that the user can enter 0 at once. So the array will not contain any valid values. In this case the array does not have a maximum value.
Your program can look for example the following way
#include <stdio.h>
int main( void )
{
enum { N = 10 };
int num[N];
int i = 0;
do
{
printf( "Enter the integer (0 - stop): " );
scanf( "%d", &num[i] );
} while ( num[i] != 0 && ++i < N );
int max_i = 0;
for ( int j = 1; j < i; j++ )
{
if ( num[max_i] < num[j] )
{
max_i = j;
}
}
if ( i == 0 )
{
puts( "You have not entered numbers unequal to zero." );
}
else
{
printf("This is the largest integer: %d", num[max_i] );
}
return 0;
}
You neither initialise nor ever write any value at all to the variable max. Using uninitialised variables is undefined behaviour.
You seem to know how to write 0 into a. But for max you seem to have it reversed. Remember that with = the value on the right of it goes into the variable on the left of it.
To fix the problem, turn any something = max; which occurs in your code into max = something;.

How to break a while loop when it is false to a certain condition

I was trying to make a program where if I enter an integer, the program would find out the bigger number and subtract it by the smaller number. This part, I got it.
The problem is, the infinite loop part.
I tried to get type in two integers keep on printing with the while loop, and break when at least one character is typed in.
For example, if I type in 2 #, it would break.
But I couldn't find the write place to get the break; within the code and therefore whenever I enter a character it would keep on creating an infinite loop.
Is there any way to create a break in this code? I humbly ask for advice...
The following is the code which I couldn't put the break
(By the way, the reason I did the condition in while as sizeof(i)==4 || sizeof(j)==4 was to make it so it would only enter an integer, since the size of an integer is 4)
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i){
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
The bottom code is the one I tried to put break but failed (it kept creating an infinite loop)...
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
if (sizeof(i) == 4 || sizeof(j) == 4) {
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
else
break;
}
return 0;
}
and here's a code where I got rid of the sizeof and used while(1), though there wasn't much change in the fact that the break didn't work...
int main()
{
int i, j;
int result;
while (1){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
You can't use sizeof(i) to do run-time checks! This is a compile-time constant that, in your case (32-bit integers) will always evaluate to 4.
In order to check that two valid integers have been given, you can check the return value of the scanf function (it gives the number of fields successfully scanned):
#include <stdio.h>
int main()
{
int i, j;
int result;
while (1) {
printf("type in two integers : ");
if (scanf("%d %d", &i, &j) != 2) break; // Break here if we didn't get two integers
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
Feel free to ask fir further clarification and/or explanation.
Drop the whole concept of endless loop with break inside if.
Make a condition for the loop based on the return value of scanf(), that is practically what it is designed for.
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
printf("type in two integers : ");
while (2==scanf("%d %d", &i, &j))
{
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
printf("%d\n", result);
printf("type in two integers : ");
}
return 0;
}
I'd probably actually use do {...} while (...) with a variable storing the return value of scanf()for being used in the loop condition. I'd consider it more elegant for not having to copy the print, but I kept it closer to your code structure.
More comments on your code:
as explained in comments, sizeof() works differently than you seem to think; it is static and does not change at runtime and hence cannot be used in a loop condition
with while (sizeof(i)==4 || sizeof(j)==4){if (sizeof(i) == 4 || sizeof(j) == 4){/* a */} else {/* b */}, b cannot ever be reached, because the conditions of while and if are identical
check the possible outcomes of the if conditions inside the loop, you are leaving the one with i==j undefined and return an uninitialised value
always init all variables as a habit
for a good MRE include the include lines
On your request, here is a proposal for the do-while alternative:
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
int iScanned=0;
do
{
printf("type in two integers : ");
iScanned=scanf("%d %d", &i, &j); /* keep the return value for loop */
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
if(2==iScanned) printf("%d\n", result); /* if to avoid awkward last output */
} while (2==iScanned);
return 0;
}

My C program to find closest pair of numbers from user input is not printing the right output?

I am trying to find the closest pair of numbers entered by the user. My C code isn't working right and I can't figure out what's wrong. I think it might have something to do with storing the values but I don't know where to go from here.
#include <stdio.h>
#include <math.h>
int main()
{
int i, j,arr[50], first,second;
//loop input
for(i=0;i<50;i++) //loop 50 times
{
scanf("%d", &i); //scan
//break if i=-1
if (i==-1)
break;
//if not print
}
//2nd num - 1st num < 3rd num-1st num, closest = 1st and 2nd num
//i[0]=num1, j[0+i]=2nd num, i= 4 , 5, 7, ans=arr,
//if j[0+i]-i[0]= ans < j[0+i]-i[i]=ans
//arr[i]=8,2,17,4,25
for(i=0;i<50;i++)
{
for(j=i+1;j<50;j++)
{
if(arr[j]-arr[i]<arr[j+1]-arr[i])
{
first = arr[i];//3
second = arr[j+1];//5
}
}
}
printf("%d %d\n", first, second);
return 0;
}
Don't post it as answer, prefer editing your code instead. Anyway, the problem is here :
for (j = i + 1; j < len; j++)//j<i <-why is it wrong?
How isn't it wrong? You've initialised j with the value i+1. How's it supposed to be ever less than i? And due to that, it's picking up values from outside the array and providing you with unexpected results.
The correct form is :
for (j = 0; j < i; j++)
The problem is with this chunk of code. You're scanning in the counter variable i instead of array. And then you're manipulating stuff using array arr. Why should that work in any scenario?
for(i=0;i<50;i++) //loop 50 times
{
scanf("%d", &i); //scan
//break if i=-1
if (i==-1)
break;
//if not print
}
And i can never be -1 unless it's a miracle.

C - Break while loop when typing the number 0 into a vector

I have this simple code that inserts the number entered in the terminal at the position of the vector at each loop.
int main()
{
int vector[5];
int i;
for (i = 0; i < 5; i++)
{
printf("Number: ");
scanf_s("%d", &vector[i]);
}
system("pause");
return 0;
}
My question is how I break the loop as soon as I type the number 0.
For example, imagine that my vector have 50 positions and I type 10 positions with positive integers numbers and now I want the loop ends when I enter zero and the rest of the 40 positions remain blank.
I imagine it's with the while loop, but I could not even get close to the result I want.
#define MAX_SIZE (5)
int main()
{
int vector[MAX_SIZE] = {0};
int i;
memset(vector, 0xFF, sizeof(vector)); //sets all vector[i] to -1 on init;
for (i = 0; (i < MAX_SIZE) && (i?vector[i-1]:1) ; i++) //you can add the condition to break from the for loop here. This is more complicated but its just for demonstration.
{
printf("Number: ");
scanf_s("%d", &vector[i]);
}
system("pause");
return 0;
}
The above sample code demonstrates the using the for loops conditional expression as a means to break the loop. The ternary in there prevents the i=0 case resulting in an out of bounds index, due to the way you structured your loop. The better/more readable way is below:
#define MAX_SIZE (5)
int main()
{
int vector[MAX_SIZE] = {0};
int i;
memset(vector, 0xFF, sizeof(vector)); //sets all vector[i] to -1 on init;
for (i = 0; i < MAX_SIZE; i++)
{
printf("Number: %d\n", i);
scanf_s("%d", &vector[i]);
if(vector[i] == 0)
{
break;
}
}
//system("pause");
printf("Broke the loop when i was %d\n", i);
return 0;
}
The difference between the two besides readability is that i will be incremented one extra time in the first one. Also, make sure to initialize all the variables you declare (all your vector elements are stack garbage, the 0xFF memset assigns them all to -1).

Question regarding allocating memory for array, sorting and numbers only in C programming

I have a program that I would like to dynamically allocate an array that gets filled by the user through the terminal argument line in Linux. After the user enters the numbers, the array of numbers should be sorted.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
int array[100];
int count = 0;
while(1){
printf("please enter a number: \n");
scanf("%d", &i);
if(i == 0){
for (int k = 0; k < count -1; k++) {
if(array[k] <= array[k + 1]){
int temp = array[k];
array[k] = array[k+1];
array[k+1] = temp;
}
}
for (int j = 0; j < count; ++j)
{
printf("%d ", array[j]);
}
printf("\n");
break;
} else {
array[count] = i;
count++;
}
}
}
This only sorts the array if I type the numbers in low to high, but if I enter the numbers from high to low eg. 4, 3, 2 and then 1, it prints 2, 3, 1 and then 4, instead of the 1,2,3,4 that it does if I type it that way.
I don't want to initialize the array with 100, I just can't get it to work if I don't initialize it. I want it to be increased if necessary.
Thank you :)
Errors/Deviations from the proposed program:
As mentioned, you want to use command line arguments - You need main(argc,*argv[]) instead of main().
For dynamic allocation you need malloc/calloc but instead of that you have used static array.
Your code shows you are not clear about concept of sorting, leave the program aside and use a pen and paper first to clear that.

Resources