C++: Flawed console output on using a conditional statement - c++

I'm a newbie to C++ (and to programming in general). I wrote a program that reads and writes staff contact details. This code works well:
// appropriate headers...
int main()
{
char trigger{};
int options = 0;
bool testing{};
fileIps Inptbox; // for entering new data
char ext_title[20]; char ext_intercomNum[4]; char ext_dept[20];
printf("%s", "Enter Officer's Title:\n");
gets_s(ext_title, 20);
printf("%s", "Enter Officer's Intercom Number:\n");
gets_s(ext_intercomNum, 4);
printf("%s", "Enter Officer's Department:\n");
gets_s(ext_dept, 20);
Inptbox.rcv_values(ext_title, ext_intercomNum, ext_dept);
Inptbox.create_string();
testing = Inptbox.validate();
if (testing == true)
return -1;
else if (testing == false)
Inptbox.write_string();
// more code below...
My question is regarding the console output. I had tried to introduce conditional statements to enable selecting a read or write mode. The above code is for writing to file. There are more lines of code below for reading from file and they, too, worked okay.
My challenge is that once I introduce a conditional statement for the above code...
printf("%s", "Enter 1 to WRITE DATA or 2 to READ DATA\n");
cin >> options;
if (options == 1)
{
fileIps Inptbox; // for entering new data
//... rest of code...
}
// more code below...
...the output on the console is flawed, as the prompt for the first entry is displayed but is totally skipped, forcing the user to enter 'Officer's Intercom Number' first. The third prompt worked well.
To elaborate further, when I used cin to assign the value 1 to options (i.e. applying the condition), the console would immediately print...
Enter Officer's Title:
Enter Officer's Intercom Number:
...making it impossible for me to fill in the first entry (i.e. 'Title').
I struggled with this and tried several things to fix it. I used fgets() and even tried it with gets(). I revisited my classes, yet nothing worked. I read widely on things like buffering, studied questions on this site and looked through various resources on cstdio as well as ios_base and its derived classes (which was good because I learned a bunch of other things). However, unless I removed that 'if' statement from my code, nothing I else I tried worked.
So, my question is: "How can this kind of behaviour be explained and how best could I implement my code to enable me toggle between read and write mode?"
I am working with MS Visual Studio 2015.

Using the formatted extraction operator '>>' has its problems. In this case, it reads all values that can convert to an integer. However, you must give an enter to signal that you're ready. The >> operator does not process that newline. When the next time input is read, it sees the previously given newline character. Hence the 'Enter Officer's title' input is immediately set to a newline and continues. Try using something like:
std::string line;
getline(cin, line);
And test the string or convert it.

Related

automate console input in C++

I am participating in few online programming exercises in C++.
Here problem description is given as to test understanding "for" loop in C++.
Input Format
You will be given two positive integers, a and b (a <=b), separated
by a newline.
Output Format
For each integer in the interval [a,b :
If 1 <=n <= 9, then print the English representation of it in
lowercase. That is "one" for , "two" for , and so on. Else if n > 9
and it is an even number, then print "even". Else if n > 9 and it is
an odd number, then print "odd".
Sample Input
8 11
Sample Output
eight
nine
even
odd
I have written program as below and test case passed.
int main() {
int a, b;
cin >> a;
cin >> b;
string num[9] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
for(int n=a; n<=b;n++)
{
if(n<=9)
cout << num[n-1] << endl;
else
if(n%2==0)
cout << "even\n";
else
cout << "odd\n";
}
return 0;
}
While I am testing, I am entering values for "a" and "b".
I can understand when I submit my code online, test cases are executed and results are shown.
My question how input is automated?. I also want to test my code with automation with out entering input at console.
Sample code for automate will be helpful. This understanding will be helpful as I move forward in working on complex
problems where more inputs will be required, so I don't want to enter manually at cin from console and want to automate this while i am testing at my laptop, just same as the way online automated test tool is doing.
Thanks for your time and help.
Usually, this is achieved through standard file descriptor overrides (which name I came up with on the spot and might be different depending on who's talking).
Considering most online compilers probably run on Linux sessions, they can simply do the following.
Build your single-file solution using (for instance) gcc -o venkysmarty-exo-3
Execute it, but override stdin to be a desired file (e.g. ./venkysmarty-exo-3 < ./test_data/exo-3/input.txt)
More generally, on most unix system and at least while running bash, the > operator can be used to redirect standard output, and < to redirect standard input. If not using file name but opened file/pipe descriptor, prefix the descriptor with & (e.g. python max.py <&64, where 64 is the file descriptor.)
On windows, in batch, the file-descriptor thing probably doesn't work, but basic >, < and >> operators seem to work the same:
So I'll answer your question 2 ways. First way, instead of asking for a value using
cin >> a
you can use
int main(int argc, char *argv[])
as your inputs in Visual Studio and to do that You go to Debug, "project name" properties, and then go to debugging. You should see something called command arguments and you can put whatever input you want in there.
The second way to do "automated" input is to put all of your input values in a file. From there you can open the file and read the values from the file. If you don't know how to read and write to a file I recommend using this link here.
http://www.cplusplus.com/doc/tutorial/files/
This solution is for Visual Studio
Have your input in a text file. On the command line redirect the input from this file.
To specify the input, set up the command line
Get Project > Properties
Under configuration properties, select debugging, then edit Command Arguments
e.g. Test input file at "C:\Projects\test.txt"
Edit command line to read "< C:\Projects\test.txt" (Without quotes

C++ Primer 1.4.4 — Importance of EOF and how to write in a code that will end without EOF?

Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).

c++ string.compare don't accept space characters

First I want to apologist about my bad title. Now the problem. I'm trying to compare two strings in C++. I had try with string.compare and ==, none of them worked. Here is code
if(game_type == "AI vs AI"){
std::cout<<"You choosed AI vs AI\n";
aiVsAI(range);
}
else{
std::cerr <<"Error";
}
and with string.compare
if(game_type.compare("AI vs AI") == 0){
std::cout<<"You choosed AI vs AI\n";
aiVsAI(range);
}
else{
std::cerr <<"Error";
}
If I give AIvsAI for input the program works correctly, but if i enter AI (space) vs (space) AI, the program prints "Error". I tried using \x20 instant of space but this didn't work too. Any ideas why this is happening?
It appears that you are using a statement similar to
std::cin >> game_type;
to obtain the user input. The problem is that the >> operator only extracts the first word from the line the user types, which makes game_type only contain AI when you type AI vs AI. (As a side note, if you were to use std::cin >> blah on the next line, then blah would contain vs because that typed input had not been consumed yet.)
To fix this, you can use std::getline:
std::getline(std::cin, game_type);
This gets everything the user types on the line (up to but not including the Enter keypress) and puts that in game_type. This is almost always the right way to get user input for an interactive program.

C++ Console INT Input Validation - Detect ENTER before no data entered?

I have this block of code form my input class I wish to improve. It works fine at the moment.
http://ideone.com/ryatJ
You use it like this... What it dose is pass a reference to the stream, and a reference to the userinput and a int to mark the max range the input has to be. The usrinput is referenced so we can use that elsewhere and it returns a true false so we can use it like this.. to get input...
while (!(validate(cin, returnval, a))){
//# Error Code code here
}
Basically everything works.. it asks the user to input a number that we are expecting as a int.
Using if (cin >> int) - I get a true false based on if the user entered a int or not. (so any string or anything... errors)
Using > and < we make sure the int is in the correct range, or it errors.
Useing peek we check the stream for a \n.. if it is not found.. it errors. (so 2.2 or 2:3 4#3 etc etc will error)
So that is all working, so well in fact I only just recently noticed that there is one more error check I need. Though I am not sure how to do it.
Basically if you just press enter with out first putting in ANY value, cin just goes to a new line. Is there a way to detect that the user just hit enter and nothing else, so I can return teh correct error message and redraw the menu screen and all the other stuff I wish to do.?
SUMMERY
How can I add to this a function to check if enter is pressed with out entering any other vales?
Thanks for the help
--Jynks
EDIT------
I can not answer my own question.. but this is the answer...
I was very close.. but the answer was in my code already.... meaning that cin.peek() is looking at the stream, at the moment it is calling it after it is read into a variable. This means it is seeing the "2nd" char and why the test works... all I needed to do was make a new test b4 the cin was read and it checked the 1st character..
Solved
http://ideone.com/mt7jH

Trying to Read a Line of Keyboard Input in C++

I mam trying to complete a college assignment in C++ and am having trouble with what should be a very basic operation. I am trying to read a string of characters from the keyboard. This is the relevant code:
string t;
cout << endl << "Enter title to search for: ";
getline(cin, t, '\n');
I understand, that the last line is supposed to read the input buffer (cin , in this instance) and store the character in the 't' string until it reaches a new line character and then continue the program flow.
However, when I run my code in XCode, it just sort of jumps over the getline function and treats 't' as an empty string.
What's going on? I tried using cin >> t but that just read characters forever - Why cant I get this to behave?
The reason that the input operation apparently is skipped, is most probably (that means, ignoring possible peculiarities of a bugsy XCode IDE) that you have performed some input earlier and left a newline in the input buffer.
To fix that, make sure that you have emptied the input buffer after each input operation that logically should consume a line of input.
One easy way is to always use getline into a string, and then use e.g. an istringstream if you want to convert a number specification to number type.
Cheers & hth.,
From the docs page it looks like you want
cin.getline(t,256,'\n');
or something similar.
This sounds like an issue with the way Xcode is running your program. Try running your program directly from the terminal, and see if this is sufficient to fix your issue.