1

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.

  • 2
    Just [ignore](http://en.cppreference.com/w/cpp/io/basic_istream/ignore) all input until there is nothing more to read. You can [peek](http://en.cppreference.com/w/cpp/io/basic_istream/peek) to see if there's more input. – Some programmer dude Feb 19 '16 at 13:34
  • @JoachimPileborg , I tried using `std::cin.ignore(std::numeric_limits::max(), '\n');` in my code but that was stopping for input :/ –  Feb 19 '16 at 13:55
  • Like cin or getline() stops for some input. and when I tried entering something, it again asked for input (this time for actual getline statement) and then printed only 2nd time one. Meaning that it discarded my first input. –  Feb 19 '16 at 13:56
  • Do you want to discard everything that was typed during a specific time interval (e.g. while the worker function is running)? Note that this only makes sense for terminals and terminal-like input streams, not for arbitrary files. C++ streams library has no functionality specific for terminals. – n. m. could be an AI Feb 19 '16 at 14:04
  • Ohhh I actually understood it, its asking for input in those cases where there wasn't any extra input. But I'm not sure how to check whether there is some extra input or not –  Feb 19 '16 at 14:04
  • @n.m., Yes I am looking specifically for terminal inputs. I'm not sure what you meant by time interval(there isn't any timer, but I may have misunderstood it), but yes I have some function that takes time to compute some stuff and then next code executes which takes input. But users might press some keywords during this time ( actually have) and then that input gets processed instead of right input. –  Feb 19 '16 at 14:08
  • There was an answer mentioning use of `std::getline()` once before asking any input and then again so that any extra input goes into that, but that means if users wouldn't have entered any input, it will hang for input. –  Feb 19 '16 at 14:12
  • [Try this](http://stackoverflow.com/questions/257091/how-do-i-flush-the-cin-buffer) – PurityLake Feb 19 '16 at 14:14
  • @JoachimPileborg If I understand correctly what you're suggesting, it necessarily involves a race condition. Could you please have a look at my answer regarding this? Feel free to downvote it if you think it's wrong - I'm curious about it. – Ami Tavory Feb 19 '16 at 14:22
  • Your comment on the `sleep(3)` line says `what to do if user enters data during this?` If my English is not failing me, "during" implies a time interval of some sort, which starts when "this" starts and ends when "this" ends. It doesn't have to be measured with a timer. – n. m. could be an AI Feb 19 '16 at 16:23
  • @oopaewem That's why I also included the `peek` part, to see if there's really is any input waiting to be read. – Some programmer dude Feb 19 '16 at 16:27
  • @JoachimPileborg How do you propose to peek? (no, `std::istream::peek` doesn't do that). – n. m. could be an AI Feb 19 '16 at 16:31
  • @n.m. during means like sleep takes 3 seconds to complete, my function could take 3 seconds to compute, or none at all depending on hardware, but usually it takes about 2-3 seconds, then during this period terminal isn't stopped and it is able to take input from user. So this starts and end points to execution lifetime of sleep(). I hope I made it clear. –  Feb 19 '16 at 17:18
  • I think I'm saying exactly the same thing. – n. m. could be an AI Feb 19 '16 at 17:26

1 Answers1

0

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.

Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • Ignore the race condition. Just assume it will never happen. (1) Put something that clears the input at your proposed potential location, (2) solve the purported race condition issue later. The problem is that you cannot do (1), so (2) is irrelevant. – n. m. could be an AI Feb 19 '16 at 17:12
  • Hmm, I was searching for something that would do like this - 1. After sleep look for extra input -> if there clear it else proceed. I do not care about `(*)` location, let user enter anything here, that would atmost mess the hint for user(rare and only if display is that slow). I care about `(**)` location where extra input is cleared before going into input variable. –  Feb 19 '16 at 17:27
  • "Look for extra input" and "clear extra input" are nice little commands. How do you write them in standard C++? – n. m. could be an AI Feb 21 '16 at 06:49
  • @n.m. I think we're looking at it from different directions. You've focused on the stream/C++ aspects (which is fine). I've focused on the timing aspects. My point was that - even if you could solve it - there would be race conditions. Your above comment "ignore the race condition" signifies your focus is different. I think there's room for considering *both* these aspects. – Ami Tavory Feb 21 '16 at 06:52
  • Your reasoning about "location 1" does not depend on actually clearing input at that point. You can just leave "location 1" blank. The purported problem happens regardless: the user can start typing stuff before the prompt appears. In fact, if there's a problem, *any* program that alternately reads user input and prints something has exactly the same problem. Clearing the input doesn't create any new problems. – n. m. could be an AI Feb 21 '16 at 08:37
  • @n.m. I know how to clear input `std::ignore()` and that solves the problem. But it creates another problem where my assumption is wrong and user hasn't pressed any keys, and then it waits to eat another `\n` character. So I need something to look for `\n`. –  Feb 21 '16 at 12:37
  • This is exactly the reason why it doesn't solve the problem. You need to know how many lines the user has typed while you were busy. You can't know that. – n. m. could be an AI Feb 21 '16 at 14:15
  • @n.m. Thanks again for your comment. IIUC, we're both saying the same thing in different phrasing (yours is "The purported problem happens regardless:..." with which I completely agree). The bottom line we're both saying about location 1 is that nothing can be solved there. – Ami Tavory Feb 22 '16 at 06:22
  • @oopaewem The more I read the comments and think about it, it occurs to me that not only can you probably not solve this, but you're attempting to create a console application that behaves differently than all other console applications. For the latter reason alone, you should consider avoiding this. Console apps don't give you this level of control - if you're looking for this, you might really be looking for ncurses, GUI, etc. – Ami Tavory Feb 22 '16 at 06:25