scanf causes loop to terminate early - c++

c='q';
while(c=='q')
{
printf("hello");
scanf("%c",&c);
}
Why does the loop exit without any reason on taking the input?

The loop isn't exiting without reason. The scanf call will read a character from stdin and store it in c, thus changing the value of c. When the loop condition is tested, presumably c no longer == 'q' (e.g., you typed something other than "q").
If you're trying to loop until the user doesn't type "q":
do {
printf("hello");
scanf("%c", &c);
}
while (c != 'q');
But note that on most console systems, scanf won't return until the user has typed a full line of text and pressed enter. If you're looking to do key-by-key entry, you'll probably want to look at a different function.

I'm going to assume you want a user input of 'q' to mean quit, and you want the loop to exit when c == 'q'.
Try:
c='\0';
while(c !='q')
{
printf("hello");
scanf("%c",&c);
}

Related

Different behaviours with getline and cin together with condition

I have a continuous while loop, inside which I get user input indefinitely until the user passes no input, i.e, presses enter, or an EOF is encountered (Ctrl+D).
The first attempt, I use getline function.
while (true)
{
if (not (std::getline(std::cin, sm)) or sm.empty())
break;
}
It works fine, exits the loop on no input or EOF.
On the second attempt I use standard cin:
while (true)
{
if (not (std::cin >> sm) or sm.empty())
break;
}
In this case, it does no longer work as intended. It does not exit the loop when user presses enter, only on entering EOF it exits.
What is the difference? What am I missing here?
Any kind of help would be appreciated.

Why doesn't my code work in visual studio?

this is my code
#include <conio.h>
#include <iostream>
using namespace std;
int main() {
bool a = false;
char b='p';
int c=0;
while (a != true) {
if (_kbhit()) {
b = _getch();
}
if (b=='w') {
c++;
cout << c << " ";
}
else if (b == 'c') {
cout << "hello";
}
}
system("pause");
return 0;
}
The problem is where when I press 'w' I want it to print out the value of c and it should be repeating until i press another input for _kbhit() right? because now it add 1 to c then prints c and when i press w again samething. What's wrong with my visual studio I'm using community 2017 I've tried to uninstall it and install it again but same problem occurs.
The problem you're running into seems to be a result of a recently added bug in _getch()/_kbhit.
For an extended key (e.g., a cursor key) it's documented that _getch() returns either a 0x0 or 0xe0 followed by the scan code for the key that was actually pressed. What's not documented is that if the user presses a non-extended key, _kbhit will still return true twice in succession, and calls to _getch() will return the key code the first time, and 0x0 the second time.
In your code, when the user presses 'w' or 'c', _kbhit will return true not just once (as you'd expect) but twice. The first time you call it, it'll return the scan code of the key, and the second it'll return a 0 byte.
What's happening in your code is that you're reading the scan code, printing something appropriately, then _kbhit is returning true again, so you read the '\0' byte, set b to '\0', and then (since you don't have any code to do anything when b is 0) you (repeatedly) do nothing until the next time the user presses a key.
Reference
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch?view=vs-2017
It seems like the program behaves the way you want it to. If I press 'w', it goes into an infinite loop of increasing the value of c and printing it. Pressing any other key stops printing and pressing 'c' goes on the same infinite loop and prints hello. Doesn't seem to be any problems as far as the posted code is concerned. Also, I would like to say the same as #Someprogrammerdude, if it compiles, but doesn't behave the way you want it to, it's an issue with the code, not the IDE and/or compiler.
Hypothetical answer: Your computer might always be thinking that a key is pressed, thus kbhit() always returns true. This maybe caused by a bad mouse/keyboard/controller driver and/or configuration. The code is fine, your PC is not.

How could I terminate my program on c++ by pressing the special character '!'?

So I am making a c++ calculator for my class assignment and I need to be able to exit the program by pressing the special character !. I have tried a do/while loop, a while loop and even the GetAsyncKeyState from the library windows.h, but nothing seems to work. The main function of my program would look something like this:
int main()
{
Stack<char> a;
char * expression;
expression=new char[30];
char * temp;
temp=new char[30];
int result=0;
bool flag=true;
cout<<"Enter an Infix Expression:";
cin>>expression;
//some more code//
.....
}
Is there a way to whenever the special character ! is pressed, store it in the char variable expression and exit the program? or what can I do to exit the program whenever that key is pressed?
Sorry, I'm new here, I don't know if I can write code in comment, so I just write a new answer
while(true)
{
cout<<"Enter an Infix Expression:";
cin>>expression;
if(string(expression).at(0) == '!')
break;
... //do your things here
}
exit(0);
//try this, and tell me if it works. I think this is better than the last one
You would have to implement your own "read stuff from stdin" function that would watch for ! and act accordingly (perhaps by calling exit() directly, or throwing an exception). I'd provide more info, but your question doesn't ask for specifics. Also, how are you parsing expressions? I ask beause ! happens to be the factorial operator, which you users might enter.
Have you tried this?
if(strcmp(expression, "!") == 0)
exit(0);

C++ User enters a non-integer value for integer variable

I am working on program where a list of options is displayed to the user and he would then enter an integer to specify which option he wants to select.Now I have pre-empted the situation where the user might enter an integer value apart from the valid ones. But if he enters any other value, say a character or a string, the program goes into an infinite loop with the list of options being printed infinitely. How can i rectify this? I mean, I should be able to give my user an error when for a predefined integer variable he enters a value that is not an integer.
Any help appreciated. Here is a sample code.
do{
printf("Select appropriate option.\n");
printf("Press 1 to do this");
printf("Press 2 to do that.\n");
printf("Press 3 to exit the program.\n");
scanf("%d",&choice);
if(choice!=1 && choice!=2 && choice!=3)
printf("You entered an invalid choice. Please enter again.\n");
switch(choice){
case 1:
//do this
break
case 2:
//do that
break;
case 3:
exit(1);
}}
while(choice!=3);
So basically when a user enters a non-integer value for choice I want the program to notify the user and ask him for another input.
It cannot be done with direct scanf into an integer variable. Such scanf will not only accept 1.23, it will also accept 1abcde and other inputs. scanf (and other conversion functions) reads as much as it can in accordance with the requested format. It stops when it finds something that does not satisfy format requirements and simply leaves it untouched.
If you want to perform this sort of analysis, you have to read the input as string and then parse and analyze that string manually.
A C-style code sketch (since you insist on C-style code, despite having tagged it as [C++]) might look as follows
char buffer[100]; /* 100 should be enough for everyone :) */
int n = scanf("%s", buffer);
if (n < 1)
/* ERROR, can't read */;
char *end;
long choice = strtol(buffer, &end, 10);
if (end == buffer || *end != '\0' || errno == ERANGE)
/* ERROR, bad format */;
/* ... */
scanf will not consume any non-digits when converting %d. It will return 0 because it didn't convert anything, and the "bad input" will still be there waiting to be consumed. You have to consume it in some way to be ready for a valid input.
(also note you're excluding 3 in your if before testing for it in your switch)
Use iostream - see http://www.cplusplus.com/reference/iostream/
Having said that if you insist on using scanf - check the return value - i.e. read http://linux.die.net/man/3/scanf
isdigit will check for any input that is a digit(number) type.
For this include header ctype.h.
Also terminate your program using exit(0) if input is incorrect.
For this include header stdlib.h.
#include<ctype.h>
#include<stdlib.h>
char c;
scanf("%c", &c);
if (isdigit(c))
{
case statement...
...
...
}
else
{
printf("Wrong input");
exit(0);
}

C++ - Quitting a program

In the C++ Without Fear: A Beginner's Guide That Makes You Feel Smart book in chapter(8), part of a code trying to display a text file is the following:
while(1)
{
for(int i=1; i <= 24 && !file_in.eof(); i++)
{
file_in.getline(input_line,80);
std::cout<<input_line<<std::endl;
}
if(file_in.eof())
{
break;
}
std::cout<<"More? (Press 'Q' and ENTER to quit.)";
std::cin.getline(input_line,80);
c=input_line[0]; // <<<<<<
if(c=='Q'||c=='q')
{
break;
}
}
The part I'm not getting here is:
c=input_line[0];
I think it is put to read 'Q' or 'q'. But, why using this form (Array)? And, isn't there a way to read 'Q' or 'q' directly?
I tried std::cin>>c; but seemed to be incorrect.
Any ideas?
Thanks.
Because input_line is string ( array from chars), so input_line[0] gets the first letter - this is in case, that the user write "quit" or "Quit", not just "Q"
std::cin >> c; would be correct, if you enter just one char and press Enter
I tried std::cin>>c; but seemed to be incorrect.
That's correct, if c is a char.
You're right; reading an entire line just to extract a single character is bizarre. I recommend a book from this list.
You are getting the first character from the "array" into which the input line has been written.
NON-STANDARD solution, but works on windows platforms.
you can use getch() function defined in conio.h
example:
#include <conio.h>
...
char c = getch();
bye