how does a do while loop used provide user prompt? - c

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.

Related

Validate integer against chars

I'm trying to make a program where the user inputs value to an array. What is actually required is that the program should validate against a char character. So if the user inputs a random char such as 'n' the program should tell him "You introduced a char, please input an integer: ".
How is that possible to make that without using a char variable?
for (i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
scanf("%d", &list[i]);
if () { // I'm blocked right in this line of code.
printf("What you tried to introduce is a char, please input an integer: ");
scanf("%d", &list[i]);
}
Thanks in advance.
As #MFisherKDX says, check the return value of scanf. From the scanf man page:
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set
indicate the error.
So capturing the return value of scanf in an int variable and then comparing that variable to 1 (in your case, because you are only attempting to read 1 item) should tell you if scanf successfully read an integer value.
However, there is a nasty pitfall when using scanf that you should be aware of. If you do type n at the prompt, scanf will fail and return 0, but it will also not consume the input you typed. Which means that the next time you call scanf, it will read the same input (the n character you typed), and fail again. And it will keep doing so no matter how many times you call scanf. It always amazes me that computer science educators continue to teach scanf to students, given not only this potential pitfall, but several other pitfalls as well. I wish I had a nickel for every hour that some CS student somewhere has spent struggling to get scanf to behave the way their intuition tells them it should. I'd be retired on my own private island by now. But I digress.
One way around this particular pitfall is to check if scanf failed, and if so, to purposely consume and discard all input from stdin up to and including the next newline character or EOF, whichever comes first.
First let's look at some unfixed code that causes an infinite loop if you enter a non-integer as input:
// Typing the letter 'n' and hitting <Enter> here causes an infinite loop:
int num, status;
while (1) {
printf("Enter a number: ");
status = scanf("%d", &num);
if (status == 1)
printf("OK\n");
else
printf("Invalid number\n");
}
The above code will (after you type n and hit <Enter>), will enter an infinite loop, and just start spewing "Invalid number" over and over. Again, this is because the n you entered never gets cleared out of the input buffer.
There are a few possible ways to get around this problem, but the consensus seems to be that the most portable and reliable way to do so is as follows:
// Fixed. No more infinite loop.
int num, status;
while (1) {
printf("Enter a number: ");
status = scanf("%d", &num);
if (status == 1)
printf("OK\n");
else {
printf("Invalid number\n");
// Consume the bad input, so it doesn't keep getting re-read by scanf
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) ;
if (ch == EOF) break;
}
}
The function scanf() will returns the number of elements read, so in this case it will return 1 every time it reads an int and 0 when it reads a char, so you just need to verify that return value.
Keep in mind that after reading a character it will remain in the buffer so if you use the scanf() command again it will read the character again and repeat the error. To avoid that you need to consume the character with while(getchar() != '\n');
With that in mind I modified your code so that it works properly printing an error message if a character is introduced and asking for a new int.
for (int i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
while (!scanf("%d", &list[i])) { //verifies the return of scanf
while(getchar() != '\n'); //consumes the character in case of error
printf("What you tried to introduce is a char\n");
printf("please introduce the value #%d of the list: ", i);
}
}

while(scanf) is infinite looping?

The code is supposed to accept a line of user input containing different characters and then print out one line containing only the letters. For example, Cat8h08er64832&*^ine would be Catherine. However, the code works and outputs "Catherine" however the program doesn't exit... see picture here I'm not sure if the loop is just looping infinitely or...
int main(void){
int i=0, j=0;
char userString[1000];
char alphabet[1000];
printf("Please enter a string: ");
while(scanf("%c", &userString[i])){
if((userString[i]>='A' && userString[i]<='Z')||(userString[i]>='a'&&userString[i]<='z')){
alphabet[j]=userString[i];
printf("%c", alphabet[j]);
j++;
}
i++;
}
printf("\n");
return 0;
}
Your problem is that you're checking that scanf is finished by checking for the return value 0. scanf returns EOF (usually, -1) when there is no more input. So if you get some input (return 1) then no more input (return -1), your loop won't ever exit.
Change the scanf condition to check for <> EOF.
This answer also explains it quite well.

How to enter a letter to quit a program in C

I am new to C programming. I have been writing this code to add numbers and I just need help with this one thing. When I type the letter 'q', the program should quit and give me the sum. How am I supposed to do that? It is currently the number 0 to close the program.
#include <stdio.h>
int main()
{
printf("Sum Calculator\n");
printf("==============\n");
printf("Enter the numbers you would like to calculate the sum of.\n");
printf("When done, type '0' to output the results and quit.\n");
float sum,num;
do
{
printf("Enter a number:");
scanf("%f",&num);
sum+=num;
}
while (num!=0);
printf("The sum of the numbers is %.6f\n",sum);
return 0;
}
One approach would be to change your scanf line to:
if ( 1 != scanf("%f",&num) )
break;
This will exit the loop if they enter anything which is not recognizable as a number.
Whether or not you take this approach, it is still a good idea to check the return value of scanf and take appropriate action if failed. As you have it now, if they enter some text instead of a number then your program goes into an infinite loop since the scanf continually fails without consuming input.
It's actually not as straightforward as you'd think it would be. One approach is to check the value returned by scanf, which returns the number of arguments correctly read, and if the number wasn't successfully read, try another scanf to look for the quit character:
bool quit = false;
do
{
printf("Enter a number:");
int numArgsRead = scanf("%f",&num);
if(numArgsRead == 1)
{
sum+=num;
}
else // scan for number failed
{
char c;
scanf("%c",&c);
if(c == 'q') quit = true;
}
}
while (!quit);
If you want your program to ignore other inputs (like another letter wouldn't quit) it gets more complicated.
The first solution would be to read the input as a character string, compare it to your character and then convert it to a number later. However, it has many issues such as buffer overflows and the like. So I'm not recommending it.
There is however a better solution for this:
char quit;
do
{
printf("Enter a number:");
quit=getchar();
ungetc(quit, stdin);
if(scanf("%f", &num))
sum+=num;
}
while (quit!='q')
ungetc pushes back the character on the input so it allows you to "peek" at the console input and check for a specific value.
You can replace it with a different character but in this case it is probably the easiest solution that fits exactly what you asked. It won't try to add numbers when the input is incorrect and will quit only with q.
#Shura
scan the user input as a string.
check string[0] for the exit condition. q in your case
If exit condition is met, break
If exit condition is not met, use atof() to convert the string to double
atof() reference http://www.cplusplus.com/reference/cstdlib/atof/

While loop with scan in 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.

do while loop for Yes/No user prompt

My program which finds prime factors is all set...the only thing left that I need to do is this type of output:
Do you want to try another number? Say Y(es) or N(o): y
//asks for another number (goes through the program again)
Do you want to try another number? Say Y(es) or N(o): n
//Thank you for using my program. Good Bye!
I have my attempt at this below...When I type n it does the correct output. But if I type 'y' it just says the same thing n does....How can I loop the entire program without putting the code for the program inside this while loop I have? So when I press y it goes through the program again?
int main() {
unsigned num;
char response;
do{
printf("Please enter a positive integer greater than 1 and less than 2000: ");
scanf("%d", &num);
if (num > 1 && num < 2000){
printf("The distinctive prime facters are given below: \n");
printDistinctPrimeFactors(num);
printf("All of the prime factors are given below: \n");
printPrimeFactors(num);
}
else{
printf("Sorry that number does not fall within the given range. \n");
}
printf("Do you want to try another number? Say Y(es) or N(o): \n");
response = getchar();
getchar();
}
while(response == 'Y' || response == 'y');
printf("Thank you for using my program. Goodbye!");
return 0;
} /* main() */
The problem is probably, that you're getting something that isn't y from getchar and the loop exits, as the condition is not matched.
getchar() may use a buffer, so when you type 'y' and hit enter, you will get char 121 (y) and 10 (enter).
Try the following progam and see what output you get:
#include <stdio.h>
int main(void) {
char c = 0;
while((c=getchar())) {
printf("%d\n", c);
}
return 0;
}
You will see something like this:
$ ./getchar
f<hit enter>
102
10
What you can see is that the keyboard input is buffered and with the next run of getchar() you get the buffered newline.
EDIT: My description is only partially correct in terms of your problem. You use scanf to read the number you're testing against. So you do: number, enter, y, enter.
scanf reads the number, leaves the newline from your enter in the buffer, the response = getchar(); reads the newline and stores the newline in response, the next call to getchar() (to strip the newline I described above) gets the 'y' and your loop exits.
You can fix this by having scanf read the newline, so it doesn't linger in the buffer: scanf("%d\n", &number);.
When reading input using scanf (when you enter your number above), the input is read after the return key is pressed but the newline generated by the return key is not consumed by scanf.
That means your first call to getchar() will return the newline (still sitting in the buffer), which is not a 'Y'.
If you reverse your two calls to getchar() - where the second one is the one you assign to your variable, your program will work.
printf("Do you want to try another number? Say Y(es) or N(o): \n");
getchar(); // the newline not consumed by the scanf way above
response = getchar();
just put getchar() after scanf statement of yours that will eat the unnecessary '\n' from buffer...
As others have stated, there is a single '\n' character in the input stream left over from your earlier call to scanf().
Fortunately, the standard library function fpurge(FILE *stream) erases any input or output buffered in the given stream. When placed anywhere between your calls to scanf() and getchar(), the following will rid stdin of anything left in the buffer:
fpurge(stdin);

Resources