While loop with scan in C - c

So my question is the following.
int n=0;
while(n<=0)
scanf("%d",&n);
This code enters in an infinite loop, and I don't have a clue why. When the user inputs a number > 0, the loop was supposed to stop.
And thanks:)

Over and over and over and over...
stdin is (generally) line-buffered - one has to press <enter> to make the terminal transfer the characters to your program. So now there's a dangling newline character in the buffer, and scanf() will try to read it during the next iteration, but it's not an integer, so it fails and doesn't change the contents of the variable. To solve this, make scanf() eat the newline:
scanf("%d\n", &number);
(Oh yes, n is also used uninitialized, but it seems that your code enters the loop anyway, so that's not the issue. Do initialize it, though, else you will face other strange errors.)

while (n <= 0)
// something
means "do something while value of n is less or equal to 0". Just make sure that n is initialized when condition n <= 0 is being evaluated. Using uninitialized variables produces undefined behavior.
You should do:
int n = 0;
while (n <= 0)
scanf("%d\n",&n);

I think you should change your compiler because i'm getting the fine result.
You might have a problem somewhere else.
You can check here.:
http://ideone.com/C4Yobi
Code:
#include<stdio.h>
main( )
{
int n = 0;
while (n <= 0)
scanf("%d",&n);
printf("%d",n);
}
Input:
-5
4
Output:
4

Since you claim to have tried things and they didn't work (although I don't see why) let's try something else. Let's use a programmer's best friend: printf. How about trying to run this code instead:
int n = 0;
while(n <= 0)
{
printf("Please enter a number: ");
scanf("%d\n", &n);
printf("I see you entered: %d\n", n);
}
printf("Done with the loop. The value of n is: %d\n", n);
This will let you see what the computer is doing and what values it reads as it reads them. Try replacing your code with the above and let's see what happens.

Related

Are there better ways to clear stdin when looking for a specific kind of input in C?

fairly new programmer here just trying to understand if there is a better way to do this and hoping to get some feedback.
TL;DR: Is there a better way to clear stdin when looking for a specific input?
For some background, I've been learning C for the past 3 weeks and scanf() has been our "go to" function for user input. After looking around for answers to this question, I'm beginning to learn that scanf() is not always preferred.
In this part of the assignment that I'm working on, I created this while loop that is supposed to run while the user input is a nonzero, positive integer. It took a while, but to get to this point I now understand that if a string is inputted instead of an integer when scanf("%d", &variable); is assigned while using leads to an infinite loop as stdin does not get cleared.
I tried to solve this problem by checking to see the return of the scanf() functions, and running the loop while the return is equal or less than 0 (which would mean that the scanf() function broke and did not return anything since it saw a char instead of an int).
The thing is, the code seems to work great until we encounter one scenario, which is where we have characters followed by an integer.
For example:
Input = 1
program runs with no issues
Input = string
program runs loop, asks for new valid input
Input = string string
program runs loop, asks for new valid input
Input = 123string
program proceeds, but then next loop with an int scanf() is infinite. 123 is stored as an int to variable.
My current understanding of the issue is that scanf() reads the integers until we get to the characters and then "string\n" gets stored to stdin, creating an infinite loop in the next part. To solve the issue, I added a fflush(stdin); before the next integer scanf() loop which seems to work.
So my question is: Would somebody be willing to show me some other ways to do this other than adding a fflush(stdin); line before every int scanf() loop? I'm sure there are better ways but I don't rightly know who to ask and the internet seemed like a good resource. Thank you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int squareLen = 0;
int numColors = 0;
int infiniteLoopStop;
// Asks for user input of desired Square Length
printf("Please enter the finished side length (in inches) of one square.\n> ");
while (squareLen < 1) {
infiniteLoopStop = scanf("%d", &squareLen);
if (infiniteLoopStop <= 0 || squareLen < 1) {
printf("\nInvalid input. Enter a nonzero, positive integer.\n> ");
fflush(stdin);
}
}
// Temporary solution to problem
fflush(stdin);
// Asks for int input of colors and loops while number of colors is not 2 or 3
printf("How many colors are you using? Enter 2 or 3.\n> ");
while (numColors < 2 || numColors > 3) {
infiniteLoopStop = scanf("%d", &numColors);
if (infiniteLoopStop <= 0 || numColors < 2 || numColors > 3) {
printf("Invalid, please enter 2 or 3.\n> ");
fflush(stdin);
}
}
printf("\n");
return 0;
}

While loop not repeating in c

I have to create a program that requests integer numbers from the user
repetitively though the keyboard until the user enters 0. I've gotten to the while loop and its not repeating and I'm not sure why. Any help would be greatly appreciated.
Thanks
Edit: I've fixed the loop in terms of it not repeating but now it's infinitely repeating and I have no clue why.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char first[30], last[30];
int n, even, odd, etotal = 0, ototal = 0;
printf("What is your first name?\n");
scanf("%s", &first);
printf("What is your last name?\n");
scanf("%s", &last);
// asks for name
printf("Enter a number\n");
printf("To quit the program enter 0\n");
scanf("%d", &n);
while (n!=0){
if(n%2==0){
printf("%d is even.\n",n);
etotal++; }
else{
printf("%d is odd.\n",n);
ototal++; }
}
return 0;
}
The loop isn't repeating because you have a return statement in the loop, that will leave the main function immediately. Just remove it.
You also have another problem that's much worse: Undefined behavior. Local non-static variables, like for example n in your code, don't get initialized, instead they have an indeterminate value. Attempting to use such an uninitialized variable leads to said undefined behavior.
You need to explicitly initialize the variable to some value before using it in the condition, for example to reorder the code so you read input before the loop and then also at the end of the loop.
Local variable n is uninitialized producing undefined results collaboratively called undefined behavior. Initialize it before entering loop:
n = 1;
And check result of scanf:
if (scanf("%d", &n) != 1)
// error
Because n is not initialized, so it has a random value:
int n, even, odd, etotal, ototal;
/* ... */
while (n!=0){
Loop is not working because you didn't initialize n and unnecessary return 0 inside the while loop. You can fix it with do..while as below. Because you have the input statement as your first statement, do..while is best opted here.
do{
scanf("%d", &n);
if(n%2==0){
printf("%d is even.\n",n);
etotal++;
}
else {
printf("%d is odd.\n",n);
ototal++;
}
} while (n!=0);
You use scanf to read your input, but after your if/else statement you are returning 0 hence you are leaving the program. So it doesnt matter if you write an even or an odd number.
while (n!=0){
scanf("%d", &n);
if(n%2==0){
printf("%d is even.\n",n);
etotal++; }
else{
printf("%d is odd.\n",n);
ototal++;
}
return 0;
}

printf after scanf always displays 1 (same unexpected value)

Okay so I'm trying to do a basic program in VS. Enter a number then it gets printed out. 1 is always printed.
int main(){
printf("Enter an integer: ");
int n = scanf_s("%d", &n);
printf("%d", n);
}
You are assigning the returned value from scanf_s() to the variable n, that means that the program will print 1 in case a successful read happened.
What you should do is
int numberOfItemsMatched;
int readValue;
numberOfItemsMatched = scanf_s("%d", &readValue);
if (numberOfItemsMatched == 1)
printf("%d\n", readValue);
I hope the variable names are self explanatory, and it's always a good idea to use this kind of names.
return type of scanf is number of items read. so if scanf is succesful in reading an item, it returns one which is assigned to n here. hence the output is 1. So separate declaration of n and scanf.

how does a do while loop used provide user prompt?

I made a simple program to make a half- triangle representing with # everything works fine only thing is that my do while loop in not working not able to prompt the user quick help?
#include<stdio.h>
int main() {
int n;
do {
printf("enter a non negitive number less than equal to 23");
scanf("%d\n",&n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
if(j <= n-(i+2) )
printf(" ");
else
printf("#");
}
printf("\n");
}
}
while(n < 23);
printf("thanks for using my program");
return 0;
}
As stated in the comments, your problem is that it prints output even when you enter a number over 23. (I am repeating this because this information is not present in the question itself.)
This is because the condition is evaluated at the end of a do ... while loop. You need to test the condition immediately after reading the input if you want to exit immediately after the number is read.
Try encapsulating the print-and-read logic in a function; this will make it easier to use as the condition in a while loop.
int prompt_and_read(int * output) {
printf("enter a non negitive number less than equal to 23: ");
fflush(stdout);
return scanf("%d\n", output);
}
Then you can do this:
while (prompt_and_read(&n) && n < 23) {
....
}
This is an improvement in multiple ways:
It flushes the output in order to make sure that the prompt gets displayed. printf() may not flush the output until a newline is written.
The loop will terminate immediately if it reads a number 23 or larger.
Because you were not checking the return value of scanf(), if the input ended before a number 23 or larger was read, the loop would continue infinitely. Testing the result of scanf() fixes this by terminating the loop if no input could be read.
If you're asking what I think you're asking...
Standard output is line-buffered, meaning output won't appear on the console until the buffer is full or you send a newline or you manually flush with fflush().
Try the following:
printf("enter a non negitive number less than equal to 23: ");
fflush( stdout );
scanf("%d",&n);
The call to fflush will force the output to appear on your console.

segmentation fault in C programming

I started learning C programming and in this program I am trying to get user input and then a line at a time and decide if it contains non-int characters. I've been trying this method:
scanf("%d", &n);
if (isalpha(n))
{
i = -1;
}
I googled a bit and learned the function isalpha is good way to do it. However, I'm getting a segmentation fault every time I test the fragment above with non-int characters (letters for example). Any suggestion would be appreciated.
The %d format specifier forces scanf() to only accept strings of digits. Given anything else, it will fail and leave n unfilled (and assuming you didn't initialize n before, it will be filled with garbage).
The crux of the problem is that isalpha() expects a value between 0 and 255, and has an assertion to enforce it. At least on my VC++ compiler, it causes a crash with an access violation when given an invalid value (in non-debug mode).
To solve this you just have to switch to a %c format specifier. Converting n to a char would also be advisable as that makes your intent of reading a single character clearer.
EDIT: Given your clarifications in the comments, you can leave everything as is and simply check the return value of scanf() instead of going the isalpha() route. It returns the number of values read successfully, so when it encounters a non-integer or end of file, it will return 0. E.g.:
int main() {
int n;
while (scanf("%d", &n)) {
printf("Got int: %d\n", n);
}
}
I have no idea why you're getting a seg-fault. I'd have to see more of your program.
But using "%d" for scanf will only accept integer values and you'll get "0" for n that isn't an integer and therefore isalpha(n) will always be false and i will never be set to -1.
Perhaps you aren't initializing i and therefore it is never set. If you are referencing it later, that's probably the source of your seg-fault.
Use scanf("%c", &n), like this:
int main(char** argc, int argv) {
char n = 0;
int i = 0;
scanf("%c", &n);
if (isalpha(n)) {
i = -1;
}
printf("you typed %c, i=%d", n, i);
}
Make sure you have a character buffer to store the value in. Scan it as a string, and then use isalpha():
char buffer[32];
sscanf("%32s", buffer);
// loop and check characters...
if(isalpha(buffer[i])) ....
Note the use of %32s, this is to prevent buffer overflows (32 == size of buffer)
Given that n is an integer, we can diagnose that you are reading a value into n which is not in the range 0..255 plus EOF (normally -1), so that the code for isalpha(n) is doing something like:
(_magic_array[n]&WEIRD_BITMASK)
and the value of n is causing it to access memory out of control, hence the segmentation fault.
Since scanf():
Returns the number of successful conversions, and
Stops when there is a non-integer character (not a digit or white space or sign) in the input stream,
you can use:
#include <stdio.h>
int main(void)
{
char n = 0;
while (scanf("%c", &n) == 1)
printf("you typed %d\n", n);
return 0;
}

Resources