I know this is a noob question. I used this example code from here. How is it supposed to work? I thought you can input something for who but it just closes immediately.
#include <iostream>
#include "getopt_pp_standalone.h"
using namespace GetOpt;
using namespace std;
int main(int argc, char* argv[])
{
string who;
GetOpt_pp ops(argc, argv);
ops >> Option('n', "name", who, "world" ); /* the default name is 'world' */
cout << "Hello " << who << "!" << endl;
return 0;
}
Variants of getopt get options from the command line rather than input by a user.
You will need to run your program with something like:
myprog -n Pax
If you want interactive input from the user, get rid of the getopt stuff altogether and just use the streams, such as:
std::cout << "Identify yourself, interloper!\n";
std::cin >> who;
std::cout << "Hello, " << who << ", my name is Pax.\n";
A few other things to impart:
First, you may need to put a getchar() (or cin >> who) before the return if you're running in an IDE that closes the execution window instead of waiting. Otherwise, the output will go to the window and immediately disappear.
Second, while it's probably okay for small programs, using namespace std can cause problems with more substantial projects (in terms of polluting the standard namespace, see here for a good explanation). I prefer to fully qualify my calls, such as:
std::cout << "blah, blah, blah\n";
Third, endl is used far too often by most developers. Most times you should just either use '\n' instead, or just tack on \n to the end of a string like "Hello, world!\n". That's because the \n way doesn't force possibly inefficient flushing of the stream like endl does. That's covered here.
Related
In my simple program to learn C++, I am asking the user their name and then greeting them.
#include <iostream>
int main() {
std::string name;
std::cout << "Enter your name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";
}
However, here is my result in CLion:
I expected the program to print out a trailing whitespace after the prompt for my name. However, it prints the space after I give the program input. I have only experienced this in CLion, but not in other IDEs. Why is this happening, and how can I fix this?
You need to flush your stream:
std::cout << "Enter your name: " << std::flush;
std::cout is a buffered stream which means that while your write to it isn't immediately written to the underlying device, but it is stored in a buffer. This is done for performance reasons. std::endl has an implicit flush operation, that's why you don't notice this if you always add a std::endl before you request input. Otherwise, like you've seen that can happen.
Edit 2:
Well, turns out I was just being dumb! It wasn't anything to do with the code at all. I was running everything via a bash script, and because of how I was using it before (which also didn't require any input) I was still running it with & at the end - so obviously I couldn't get any input from that shell.
My program seemingly skips the line were I try to receive input using cin (it goes right to the next line).
Edit: Please look at the bottom where I put the new code and what happens.
I've searched here and googled, and I've found a lot of questions where people had the same problem! As far as I understand, the problem was almost always a leftover '\n' - but none of the solutions have worked for me sofar. This is the problematic code:
//char input_char;
std::string input_string;
//int input_int;
//std::string line;
std::cout << "hello. your input: ";
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
std::cin >> input_string;
// std::getline(std::cin, input_string);
std::cout << "input: " << input_int << endl;
I only need one character or number. I've tried it with a character, int, or string; and I've tried cin and getline. I've added clear and ignore as was suggested for other similar questions, but I still have the same problem.
This is at the beginning of my main, so I'm not doing any other cout or cin before this code. However, this is part of a larger project, and I'm using ros. Before the program gets to this part, there are other outputs which are handled through ros; no other input though.
I'd very much appreciate you help with this! I feel like I must be missing something really obvious...
Edit: I've now commented out literally everything that isn't immediately related to this input, and moved cin to the very top of the main. This is now the complete code (commented parts left out):
#include <iostream>
#include <ros/ros.h>
#include <vector>
#include <ros/console.h>
#include "std_msgs/String.h"
//#include <SharedMessages/MicroconRequest.h>
/* ... */
//ros::Publisher reqPublisher;
//SharedMessages::MicroconRequest reqMsg;
/* ... */
int main( int argc, char* argv[] )
{
char input_test;
std::cout << "character: ";
std::cin >> input_test;
std::cout << input_test;
std::cout << "did that work?";
// Handle ROS communication
ros::init( argc, argv, "Gestures" );
ros::NodeHandle n;
//ros::Subscriber joy_sub_ = n.subscribe<sensor_msgs::Joy>("joy", 10, joyCallback, this);
//reqPublisher = n.advertise<SharedMessages::MicroconRequest>("MicroconRequest", 10);
ros::Rate loop_rate(10);
// Infinite control loop
while (ros::ok())
{
/* ... */
cntLoop++;
ros::spinOnce();
loop_rate.sleep();
}
// turn off microcontroller
return 0;
}
Now what happens is the following:
$ ./startDemo.bash
Starting Minimal Example
$ character: a # now I have time to input something, but...
a: Befehl nicht gefunden. # = command not found]
# then it doesn't do anything, so I stop it
$ ./stopDemo.bash
killing /Gestures
did that work?[ WARN] [1473954737.268901991]: Shutdown request received.
[ WARN] [1473954737.268978735]: Reason given for shutdown: [user request]
killed
$
Only after killing the program does the output suddenly appear. What is happening here? I'm so confused.
I don't understand your original question about skipping a line but the reason nothing is printed until you shutdown is that you are missing the endl from the output. I added it and the output seems as you would expect?
char input_test;
std::cout << "character: ";
std::cin >> input_test;
std::cout << input_test;
std::cout << "did that work?" << std::endl;
Output:
root#93043381199d:/catkin_ws/devel/lib/stack# ./stack_node
character: a
adid that work?
Well, turns out I was just being dumb! It wasn't anything to do with the code at all:
I was running everything via a bash script, and because of how I was using it before (which also didn't require any input) I was still running it with & at the end - so obviously I couldn't get any input from that shell.
[Note: I wasn't sure if it was good practice to answer one's own question; at first I just edited it. But I figured it'd make more sense than to just leave it open.]
Here is an example code demonstrating the problem I'm facing.
#include <iostream>
#include <string>
extern "C" {
#include <unistd.h>
}
int main()
{
std::cout << "Making tests ready!" << std::endl;
std::cout << "\nTo start out, Enter an integer: ";
int a = 0;
std::cin >> a;
std::string input;
sleep(3); // what to do if user enters data during this?
std::cout << "\n Now enter a string";
std::getline(std::cin, input);
std::cout << "\nHere are your values - " << a << " & " << input;
return 0;
}
See the sleep call in between the code? This could be replaced with somewhat long delays while computing something when my program isn't accepting any inputs. Now if user presses some keys during this time, that input is captured by std::getline() in next line of code. I know this is the default behavior since it should capture the input being provided.
But what I want is to clear all that captured input and start fresh with 15th line that is std::cout << "\n Now enter a string";, which is immediately after sleep. I don't know exact term to describe this or else I would have used that. Thanking you.
Edit: I've tried using std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); in my code, but it asks for input and then discards it.
Please mind my english, not a native speaker.
Reading the comments causes me to think that you can't really solve this problem (at least by the means suggested there). There's an inherent race condition in any case. Consider the following lines:
sleep(3);
// (*) <- Potential location 1.
std::cout << "\n Now enter a string";
// (**) <- Potential location 2.
std::getline(std::cin, input);
The various comments show some (very technically-competent) ways to flush the standard input. The problem is, you cannot put them in the location marked (*) nor (**).
First location - you clear the standard input some way. Now you decide it's time to move to the next line (std::cout << ...). While you do that, the user types in some more input. Race!
Second location - You print out the message (std::cout << ...), and proceed to clear the standard input. Before you manage to do that, the user typed in something. Race!
It seems to me that any of the techniques described in the comment require locking the standard input, and I don't think there's a (standard) way to do so.
So if I write a piece of code like this:
string name, feeling;
cout << What is your name?" << endl;
cin >> name;
cout << "Hello, " << name << "!"<<endl;
cout << "So how are you feeling today?" << endl;
cin >> feeling;
I get the output:
What is your name?
James (input from user)
Hello, James!
So how are you feeling today?`
But I want it to remove the first message and the input, so the user will get just this on the console window:
Hello, James!
So how are you feeling today?
As long as you stay on the same line, it's usually pretty easy to use a combination of \b (back-space) and/or \r (carriage return without new-line) and some spaces to go back to the beginning of a line and write over what's displayed there.
If you need to do (much) more than that, you can use the Windows console functions such as SetConsoleCursorPosition and FillConsoleOutputCharacter to write data where you want it, overwrite existing data, etc.
If you care about portability to Linux and such, or already know how to program with curses, you might prefer to use PDCurses instead. This is basically a re-implementation of the ncurses programming interface on top of the Windows console functions.
If you work on windows environment, try this
#include <iostream>
int main()
{
std::cout << "This is the first line";
system("cls");
std::cout << "This is the line on clear console" << std::endl;
return 0;
}
This program:
#include <iostream>
#include <cstdlib>
#include <string>
int main(int argc, const char *argv[])
{
using ::std::cerr;
using ::std::cout;
using ::std::endl;
if (argc < 2 || argc > 3) {
cerr << "Usage: " << argv[0] << " [<count>] <message>\n";
return 1;
}
unsigned long count = 10000;
if (argc > 2) {
char *endptr = 0;
count = ::std::strtoul(argv[1], &endptr, 10);
if ((argv[1][0] == '\0') || (*endptr != '\0')) {
cerr << "Usage: " << argv[0] << " [<count>] <message>\n";
return 1;
}
}
const ::std::string msg((argc < 3) ? argv[1] : argv[2]);
for (unsigned long i = 0; i < count; ++i) {
cout << i << ": " << msg << '\n';
}
return 0;
}
when timed like so:
$ time ./joe 10000000 fred >/dev/null
real 0m15.410s
user 0m10.551s
sys 0m0.166s
takes 15.4 seconds of real time to execute. Replace the output line with this: cout << i << ": " << msg << endl; and you end up with something like this:
$ time ./joe 10000000 fred >/dev/null
real 0m39.115s
user 0m16.482s
sys 0m15.803s
As you can see, the time to run more than doubles, and the program goes from spending minimal time in the OS to spending nearly half of it's time in the OS.
Both versions of the program have identical output, and are guaranteed by the standard to have identical output on every platform.
Given this, why do people persist in using endl as a synonym for '\n'?
Edit: In case it isn't obvious, this question is intended to be a leading question and is here for instructional purposes. I know why the performance penalty exists.
I'm not certain. Inserting std::endl into the output stream is defined as being equivalent to inserting .widen('\n') and then calling flush() and yet many programmers persist in using std::endl even when there is no cause to flush, for example they go on to immediately output something else.
My assumption is that it comes from an incorrect belief that it is somehow a more portable because it doesn't explicitly use a specific newline character. This is incorrect as \n must always be mapped to the system's correct newline sequence for non-binary files by the stream library.
Afaik, endl also flushes the stream, which may be the cause of the performance penalty.
Not everyone cares so much about performance. For some applications, guaranteeing the stream is flushed is much more important.
Edit: Also, I find endl easier to type than '\n' :-)
I tend to use endl with on stringstreams as it makes it easy to spot missing linebreaks.
My guess is that instructional texts use std::endl with the belief that it's simpler and less confusing for beginners, and afterward people got accustomed to using it.
The real question is, why did the compiler make such a dogs breakfast of compiling the endl version? If they're guaranteed to have the same semantics, then they should also have the same runtime.
Edit: obviously, I wasn't aware that endl flushed the stream... that's what you get for not looking it up.