#include<stdio.h>
int main(void)
{
int i=2,number;
printf("Enter another number greater than 5\':");
scanf("%d",number);
while (number>5);
for (; i<=3; i++)
{
printf("Hi\n");
++i;
}
printf("Enter another number greater than 5\' to continue the cycle:");
scanf("%d",number);
printf("finish");
return 0;
}
First, within the two scanf functions you need to add & to the number parameter. It is because &number gets the address of number, and the value entered by the user is stored in that address. Also, your code never leaves the loop. Try like this:
#include <stdio.h>
int main(void){
int number;
printf("Enter a number greater than 5: ");
scanf("%d",&number);
while (number>5){
for (int i = 0; i<1; i++){
printf("Hi\n");
}
printf("Enter another number to continue the cycle: ");
scanf("%d", &number);
}
printf("finish");
return 0;
}
Remember that for loop already increments the counter i by itself, so the i++ statement inside loop is unnecessary if you wanted to print "Hi!" only once (even the for loop is useless if you only wanted to print it once, but I guess you did it because you are learning).
There are several problems:
1 Incorrect usage of scanf
scanf takes format string and then addresses to variables, so it could write to memory, where the variables are located.
So correct usage is
scanf("%d",&number);
Best would be to check also return value of scanf. scanf returns count of successfully loaded arguments. So in you case
if (scanf("%d", &number) != 1) {
// print error message, or something else
}
If there were more arguments, then the condition would be different
if (scanf("%d %f %c %d", &a, &b, &c, &d) != 4) {
// ...
}
2 Infinite while loop
while (number>5); is infinite loop if number is greater then 5.
number is not changed within the loop, so the condition for while loop would be always truthy.
3 Possibly wrong incrementation of i variable in for loop
// int i = 2;
for (; i<=3; i++)
{
printf("Hi\n");
++i;
}
There is suspicious ++i; in the for loops body. This does not change the for loops behaviour, but I assume you are a beginner, so I will explain it anyway.
It will work like this:
for loop starts with no initialization (i is initialized to 2 outside of the loop)
condition i <= 3 gets evaluated to 1 (C does not have boolean [true,false], so there are used numbers instead [0 == false, anything else == true])
printf("Hi\n"); gets evaluated -> "Hi\n" gets printed
++i; gets evaluated -> i gets incremented to 3
update of for loop gets called (which is i++) -> i gets incremented to 4
condition i <= 3 gets evaluated as 0, because 4 (value of i) is greater then 3
for loop gets finished
My point here is that the i is incremented twice every loop.
So it's the same like
for(; i <= 3; i += 2) {
scanf("%d", &number);
}
Related
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 don't know much about modularity except it's basically dividing up your code into smaller groups of functions (this question is for the C language).
I'm doing an assignment where I can only see my source code working with one giant nested loop in "main" (no if statements are allowed for the assignment). In other words, if I try and use functions to cut up the code, I don't see how the necessary nested loop will work. But the assignment requires an attempt at modularity.
Thus, can anyone tell me how I might break up the following code into smaller modules without messing up its actual execution?
#include <stdio.h>
int main(void)
{
int counter = 0;
int marknum = 0;
int sectioncode, studentnumber;
int dummyvariable = 0;
int index;
int marks;
int total = 0;
do
{
printf("Enter a Section Code: ");
scanf("%d", §ioncode);
while(sectioncode > 4 || sectioncode < 1)
{
printf("Invalid value entered. Must be 1 to 4, please re-enter: ");
scanf("%d", §ioncode);
}
do
{
printf("Enter the Student's ID: ");
scanf("%d", &studentnumber);
while (studentnumber < 1 || studentnumber > 999999999)
{
printf("Invalid value entered. Must be 1 to 999999999. Please re-enter: ");
scanf("%d", &studentnumber);
}
while (sectioncode != 0)
{
while (counter < 5)
{
counter++;
marknum++;
printf("Enter mark%d: ", marknum);
scanf("%d", &marks);
total = total + marks;
}
printf("%09d's total mark is %d\n", studentnumber, total);
counter = 0;
marknum = 0;
sectioncode = 0;
}
dummyvariable = 1;
} while (dummyvariable = 0);
} while (sectioncode != 0);
return 0;
}
Also, how would I incorporate modularity for this one (same question basically):
#include <stdio.h>
int main(void)
{
int num; //User inputted number
int i; //Increment variable
char ch; //Check for characters variable
do //Begin "do while" loop
{
printf("\nEnter a number:"); //User prompt
scanf ("%d", &num); //Scan for user inputted integer
while ( (ch = getchar()) != '\n') //Scan for character, check for non-numeric input
{
printf("Invalid number entered. Please re-enter: "); //Error message and prompt for invalid user input
scanf ("%d", &num); //Scan for user inputted integer
} //Repeat loop if condition becomes true again
for (i=0; i<num; i++) //Begin "for" loop; condition prints asterisks equal to user number; increment i by 1
{
printf("*"); //Prints a single asterisk each loop until i is less than num
}
} while (num!=0); //Stop "do while" loop if user enters 0
return 0;
}
Normally I'd suggest that you ask your instructor instead of asking homework questions here, but as Daniel points out in the comments, the use of loops and extra variables just to avoid having if statements in the code is stupid, and I'm not sure telling you to get advice from an instructor who thought that was a good idea would be entirely responsible behavior on my part. So, having said that:
What you want to look for in cases like this is multiple chunks of similar code, or chunks of code that conceptually do a single thing. Then see if you can split those chunks out into a function.
In the first example, you display a prompt, read user input, and verify the input for both sectioncode and studentnumber. That process could be split into a separate function. (Everything from printf("Enter ...") through the end of the while loop.) Then in the main function, you just have something like
sectioncode = readval("Enter a Section Code: ", 1, 4);
studentnumber = readval("Enter the Student's ID: ", 1, 999999999);
For the second example, that input/validation code isn't duplicated, but it's still probably worth splitting out into a function, since it does a single well-defined thing, and spans enough lines that splitting it out into a function might help make the logic of the remaining code more clear. But it's less important in this case than in the first.
Also, an unrelated issue: At the end of one of the do-whiles, you have while (dummyvariable = 0);. Note the single equal sign. You're assigning 0 to dummyvariable, not comparing.
In this particular case, it works anyway, since the whole expression evaluates to 0 (i.e. false), just like (dummyvariable == 0) would have. But if that constant had been anything else, or if you hadn't just set dummyvariable to 1 prior to the end of loop, that'd be a bug.
I strongly recommend always putting the constant on the left hand side of expressions like that in order to catch bugs of that sort at compilation. while (dummyvariable = 0) silently does something unexpected; while (0 = dummyvariable) will give an error at compile-time, and you can fix it.
I've looked at multiple solutions but none of them worked for me.
I'm asking the user to enter numbers in a loop, but if the user enters a specific number the loop should break.
This is what I've got so far.
#include <stdio.h>
#include <stdlib.h>
#define MAXNUMBERS 5
int getNumbers(int array[])
{
int i;
int n = 0;
printf("Enter max. %d numbers, enter empty line to end:\n", MAXNUMBERS);
for (i = 0; i < MAXNUMBERS; i++)
{
scanf("%d", &array[i]);
fflush(stdin);
n++;
if (array[i] == '5')
{
break;
}
}
return n;
}
int main()
{
int array[MAXNUMBERS];
int amount_numbers;
amount_numbers = getNumbers(array);
printf("Numbers entered: %d\n", amount_numbers);
printf("First three: %d %d %d", array[0], array[1], array[2]);
return 0;
}
Input:
1
5
4
3
2
Output:
Numbers entered: 5
First three: 1 5 4
If the user enters 5 the loop should break.
I'm using 5 as an example, I later want it to do with an empty line. But it doesn't even work with 5.
It just keeps prompting the user to enter another number after he entered 5.
The actual problem is '5' != 5 the former is the character 5 which is in fact it's ascii value, and the latter is the number 5, since you are reading integers, i.e. using the "%d" specifier in scanf() you should use 5, but it would be better if it was just a int variable, and you could initialize it to any number you like before the loop starts.
Your loop is wrong anyway because if the user enters a non-numeric value then your program will invoke undefined behavior. Besides you already invoke undefined behavior with fflush(stdin), so
Remove fflush(stdin)1
7.21.5.2 The fflush function
If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is
undefined.
So the behavior is undefined for an input stream like stdin, or even if the most recent operation was input.
You must check that the value was read properly, and then check in the loop condition if it equals the value you want to stop the loop with, try this
int readNumber()
{
int value;
printf("input a number > ");
while (scanf("%d", &value) == 1)
{
int chr;
printf("\tinvalid input, try again...\n");
do { /* this, will do what you thought 'fflush' did */
chr = getchar();
} ((chr != EOF) && (chr != '\n'));
printf("input a number > ");
}
return value;
}
int getNumbers(int array[])
{
int i;
int stop = 5;
printf("Enter max. %d numbers, enter empty line to end:\n", MAXNUMBERS);
array[0] = 0;
for (i = 0 ; ((i < MAXNUMBERS) || (array[i] == stop)) ; i++)
array[i] = readNumber();
return i;
}
1This is a quote from the C11 draft 1570.
if (array[i] == '5')
You're checking whether array[i] is equal to the ASCII value of the character '5'.
Remove the '' to make it compare against the integer 5.
You are checking if an integer is equal to the character '5', which is then being cast to an ascii value of '5'.
Try using this:
if (array[i] == 5)
Disregard everything!
I should have written
if (array[i] == 5)
without the quotes!
I'm an idiot!
I sat 2 hours at this error...
I'm trying to create a program that will take inputs into an array, and then print them all when input is terminated. My understanding was that when you declare a variable outside of the loop, it keeps the values, but I can't get this to work out. I know there's a way to do this somehow, but I'm drawing a blank.
#include <stdio.h>
int main(){
int i=0;
int n=0;
int size=0;
int numbers[i];
scanf("%d", &numbers[i]);
while ((i = 1 && numbers[i-1] != 42)){
scanf("%d", &numbers[i]);
i++;
size++;
//printf("%d",numbers[i]);
}
printf ("%d", sizeof(numbers));
while ((n = 0 && n < sizeof(numbers))){
printf("%d", numbers[i]);
printf("\n");
++i;
++n;
}
}
Your while condition:
(i = 1 && numbers[i-1] != 42)
has two problems:
i = ... actually assigns a value to i. In cas of unexpected looping, allways check if there's a =instead of an == in the condition
due to operator precedence, you assign 1 && to i. That's true value (i.e. 1) as long as you're in the loop, and as soon as numbers[i-1] is 42, i turns to 0 (because numbers[i-1]!=42 is false and 1 && false is false i.e. 0 ). This gives you impression that it didn't keep the value.
Edit: Of course, it's the same principle for n in the second loop ;-)
3 things in your code:
int numbers[i]; is trying to declare a zero element array, which accounts to undefined behavior.(although there's no bound/range checking in C)
scanf("%d", &numbers[i]), when i>=1 where is the storage allocated for this? mostly would end up in an undefined area/ over writing an existing value.
Refer the following links for more information:
Declaring an array with 0 number of elements can still store values
Why does C not define minimum size for an array?
that said you could either declare an array of fixed size or declare the size dynamically using malloc, then loop through the elements , assign and print them.
-the while loop: evaluation and priority of operators:
you could re-write your program as:
#include <stdio.h>
int main(){
int i=0;
int n=0;
int size=0;
int numbers[42];
scanf("%d", &numbers[i++]);
while (((numbers[i-1] != 42)))
scanf("%d", &numbers[i++]);
size=sizeof(numbers)/sizeof(int); /* Not necessary as array size pre-defined*/
printf("\nsize:%d\n",size);
while(n < size)
printf("%d\n", numbers[n++]);
printf("\n");
}
Note: you can change the size of the array, do keep in mind that it's an automatic variable and those array elements which haven't been explicitly initialized would be filled with junk values.
There are a lots of mistakes in your code.They are as follow-
1.int i=0;
int number[i]; which makes no sense. because you are creating an array of size 0
while ((i = 1 && numbers[i-1] != 42))
every time you while loop iterates it sets the value of i to 1 and compares numbers[0]!=42 which also makes no sense.
while ((n = 0 && n < sizeof(numbers)))
again you are assigning n to 0 and checking if n is less than sizeof(numbers) which is always true.
Although you did not specify your problem correctly I am assuming that you want to scan number till you get 42. And after that you want to print the size of the array and the numbers too.
Here is your working code.
#include <stdio.h>
int main(){
int i=0;
int n=0;
int size=1;
int numbers[10000];//I am assuming maximum input to be 10000
scanf("%d", &numbers[0]);
i=1;
while (( numbers[i-1] != 42)){
scanf("%d", &numbers[i]);
i++;
size++;
//printf("%d",numbers[i]);
}
printf ("size=%d\n", size);
while ( n < size){
printf("%d", numbers[n]);
printf("\n");
//++i;
++n;
}
}