I have a very simple problem in C. I am trying to write a simple program that outputs multiples of 10 between 10 and 100, inclusive (ie: on the closed interval [10,100]) that skips 30 and 70 and outputs the values vertically.
Here is my code:
#include<stdio.h>
main()
{
int i=10;
do {
if(i==30||i==70)
continue;
printf("\n %d",i);
i++;
} while(i<100);
return 0;
}
The program stops at 29 skips 30 and continues into a never ending loop. What is wrong?
The problem is that when you hit the if statement, you are now skipping the increment of i. So you never reach 100!
#include<stdio.h>
main()
{
int i=10;
do {
if(i==30||i==70)
continue; //!!!! This will skip the i increment
printf("\n %d",i);
i++;
} while(i<100);
return 0;
}
I recommend a for loop:
main()
{
for (i = 10; i < 100; i++) {
if(i==30||i==70)
continue; // The for loop will do the i++ on the "continue"
printf("\n %d",i);
}
return 0;
}
mbratch correctly pointed out your problem, but you might want to consider a for loop for this sort of thing. It would have prevented this particular problem, since the increment is automatic.
I won't do the whole thing for you, since you're obviously trying to learn, but this ought to get you started:
for (i=0; i<100; i+= 1)
You'll have to change some of the numbers in that line, but hopefully you'll understand what they mean when you change them.
When i reaches 30 the continue statements moves back to the start of the loop.
And so the loop continues endlessly as i is not incremented from this point.
Your code's doing exactly what it's written to do. The continue skips the increment instruction, so the value hits 30 and gets stuck there. Move the increment to the start of the loop body, or better yet, use a for instead of a while.
Don't use continue. Instead print out the value as long as != to 30 and 70. Also iterate by 10 instead of 1 to output multiples 10.
#include<stdio.h>
main()
{
int i = 10;
do
{
if (i != 30 && i != 70)
printf("\n %d", i);
i += 10;
}
while (i <= 100); // if you want to print 100
return 0;
}
Output:
10
20
40
50
60
80
90
100
Use while (i <= 100); if you need to also print 100.
It loops forever because you continue but don't increment i.
if(i==30||i==70) {
i++;
continue;
}
or you could use a for loop like so,
#include<stdio.h>
int main()
{
int i=10;
for (; i < 100; i++)
{
if(i==30 || i==70) {
continue;
}
printf("\n %d",i);
}
return 0;
}
The reason is that i is never incremented after 30 inside the body of do..while. You'd need to increment it.
if (i == 30 || i == 70){
i++;
continue;
}
Related
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.
I am taking input in an array of length 100 using scanf in a loop. After 20 numbers, if I enter -1, I want the loop to exit, i.e finish taking input and continue with the rest of the program. I am doing something like this
for(i=0;i<100;i++)
{
scanf("%d", &input[i]);
if(input[i] == -1)
{
break;
}
}
I heard, it is bad practice to use break statements even though this code works perfectly fine. So I was wondering what is a more efficient way to end the loop when -1 is entered. I tried
for(i=0;scanf("%d",&input[i])!=-1;i++)
also
fori(i=0;i<100;i++){
do
{scanf("%d", &input[i]);
}while(input[i]!=-1
}
Neither of these don't work
The second expression of the for loop is a free-form boolean expression. In this case you could add your condition there. However in this case it wouldn't look exactly nice. For example
for(i=0; i < 100 && (i < 1 || input[i - 1] != -1); i++)
{
scanf("%d", &input[i]);
}
I.e. if we have already input one value, check the value and that must be inequal to -1 for the loop to continue
Another would be to use a synthetic flag variable:
int loop_again = 1;
for (i = 0; loop_again && i < 100; i++) {
scanf("%d", &input[i]);
if(input[i] == -1)
{
loop_again = 0;
}
}
All in all, these both look way uglier than just using the break statement for the very thing that it was invented for.
Note that you also should check the return value of scanf itself!
it is bad practice to use break statements
As Ancient Greeks said, "Pan Metron Ariston", which means that everything that is used with balance is great. This applies here too, and your code as is, is good to go. The only thing to be worried about is not checking the return value of scanf().
Now if you really insist on changing your approach, then please refer to Haapala's answer, we got there first.
You can use a while loop and check for -1 in the input in the loop conditional. Note that you should always check the value returned by scanf(). In the posted code, non-numeric input results in no value being stored in input[]; this may lead to undefined behavior later if the code attempts to use an indeterminate value.
Here is an example. Note that the loop conditional first checks whether the array index has grown too large, then checks the return value from scanf() to be sure that a number was entered, then checks to see if -1 was entered. In the case of non-numeric input, the loop is terminated.
#include <stdio.h>
#define INPUT_SZ 100
int main(void)
{
int input[INPUT_SZ];
size_t i = 0;
while (i < INPUT_SZ && scanf("%d", &input[i]) == 1 && input[i] != -1) {
++i;
}
puts("You entered:");
for (size_t j = 0; j < i; j++) {
printf("%d\n", input[j]);
}
return 0;
}
Sample interaction:
2 4 6 8 -1
You entered:
2
4
6
8
You can simply change the value of counter variable to max, then it'll automatically come out of loop.
#include<stdio.h>
#define MAX 10
int main()
{
int ar[MAX], i, count;
for(i=0; i<MAX; i++)
{
scanf("%d", &ar[i]);
if(ar[i]==-1)
{
count=i--; //this is your new MAX. Not mandatory but will be useful if you need to access array elements
i=MAX;
}
}
//printing array
for(i=0; i<count; i++)
{
printf("Element %d: %d\t", i+1, ar[i]);
}
return 0;
}
Hope this helps.
Use a do-while loop
int i=0;
do{
if(scanf("%d", &input[i++]) != 1)
{
if(i>0)
--i; // Decrementing i if an integer is not provided
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) // Wasting the buffer
;
}
}while(input[i-1] != -1 && i<=99);
i work for a question that generate random number and sort in array, then display numbers from biggest to smallest.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 40
int main()
{
int array[SIZE];
int inner, outter, temp, i;
srand((unsigned)time(NULL));
//do... while to assign array value
i=0;
do{
array[i] = (int)((rand()%101)+1);
i++;
}while(i<SIZE);
puts("Original array:");
for(outter=0; outter<SIZE-1;outter++){
printf("%d\t", array[outter]);
}
//bubble sort
for(outter=0; outter<SIZE-1;outter++){
for(inner=outter+1; inner<SIZE; inner++ ){
if(array[outter] > array[inner]){
temp = array[outter];
array[outter] = array[inner];
array[inner] = temp;
}
}
}
puts("\n");
puts("Sorted array:");
printf("i= %d\n",i);
printf("%d\n", array[39]);
for(outter=0; outter<SIZE;outter++){
printf("%d\t", array[outter]);
}
puts("\n");
for(outter=SIZE-1; outter>0;outter--){
printf("%d\t", array[outter]);
}
puts("\n");
// try using do while loop to display reverse number from biggest to smallest numbers
do{
printf("i= %d\n", i-1);
i--;
}while(i>-1);
}
when i used do while for displaying reverse array number, my code goes crush.
However, i display the value the "i" that used for looping array, it displayed from 39 to -1. I don not why i have -1 for "i" value since i set "i>-1".
TL;DR: Either change your printf to this: printf("i= %d\n", i); or change your while loop to while(i > 0);. Either way, it should fix your problem.
A do while loop does the action in the curly braces and then checks the condition. I'm not quite understanding your question, but it seems to me that it's printing -1 because it's doing first, then checking the condition. Furthermore, you're using i - 1 in your printf function (which is probably where you've confused yourself the most).
EDIT: To be even more explicit about the while loop, the problem is that your condition is (i > -1). That means that when you reach 0, your code will check: is 0 greater than -1?. It will return true and then move on the i = -1 where it prints -1. Then it reaches the while condition once more where it sees that -1 is not greater than -1 which is when the code terminates.
Your main problem is probably the starting value for i.
After the first do ... while loop it equals 40 when the condition fails.
Therefore you could make things a lot easier if you adjust your starting value for the second loop:
i--; // or i = SIZE-1;
do{
printf("i= %d\n", i);
i--;
} while (i >= 0);
Then you don't have any headache by shifting your values by one and can just use the values you want.
If you insist on doing it the way you did, then check the limits...
do{
printf("i= %d\n", i-1); // last value to be printed is 0 ==> i == 1
i--; // The last wanted value of i now is 0.
} while (i>0); // Stop if we reach last wanted value
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])
};
I have the following code in C:
#include <stdio.h>
int main()
{
int i = 1;
while(i)
{
int index = 0;
printf("while begin\n");
for(index = 0; index < 10; index++)
{
if(index == 2)
{
continue;
}
printf("within for\n");
}
printf("while end\n");
}
printf("returned from while");
}
does the continue effect the for loop or the while loop directly? looks like once the continue is called, for loop will start to run from the beginning, should not the while loop start to run from the beginning?
continue will cause the remaining portion of the enclosing for or while loop body to be skipped. In your case, the for is the "enclosing" loop of continue and the while loop is the "enclosing" scope of the for loop.
According to (unofficial) documentation
The continue statement causes a jump, as if by goto to the end of the
loop body (it may only appear within the loop body of for, range-for,
while, and do-while loops).
To understand what continue is you should know what break does too.
So the following peace of code shows you how break and continue works:
#include <stdio.h>
int main(void){
int hours = 10;
int i=0;
for(i=0;i<hours;i++){
if(i==5){
break;
}
printf("%d ",i);
}
return 0;
}
Output:
0 1 2 3 4
As you can see, when i reaches 5 (i==5) the loop breaks.
Now let's take a look of what does continue if we replace break using the same code:
#include <stdio.h>
int main(void){
int hours = 10;
int i=0;
for(i=0;i<hours;i++){
if(i==5){
continue;
}
printf("%d ",i);
}
return 0;
}
Output:
0 1 2 3 4 6 7 8 9
As you can see it doesn't leave the loop (like when using break), instead when i reach 5 (i==5) ignore the rest of the body making the loop to start over from the point where i was last time seen.
The number 5 *is missing.
The simplest way to think about it is to say : "it goes back to the top of the loop" anything AFTER the continue won't be processed.