Avoid halting the program with getline()

I'm writing a program which needs to be able to read data from stdin with getline(), cin or some other method, but only if there IS something to read. Otherwise it should not halt the entire run of the program (I mean not wait until the user enters an input)
Is there a way to implement this?
use peek()
http://www.cplusplus.com/reference/istream/istream/peek/

but you wont know if the user has finished typing, just that they have typed something, they could still be typing while you are calling peek(), you will probably need to manage the conversion from input text to code data yourself as cin >> myInt; isnt going to work.

After writing that, it sounds like a lot of work, so perhaps it would be simpler to create a background thread to gather user input and pass to the program.
Last edited on
Jaybob66 wrote:
use peek()

peek() also waits for input if there isn't any.
Last edited on
not according to http://www.cplusplus.com/reference/istream/istream/peek/

If there are no more characters to read in the input sequence, or if any internal state flags is set, the function returns the end-of-file value (EOF)
If the stream has not ended (e.g. the user hasn't pressed Ctrl+D or closed the console window) there is no way to know if there are more characters to be read so it'll just have to wait.
Last edited on
Thanks Peter,

the while loop below did NOT work, "waiting.." was never printed, as you predicted :)


1
2
3
4
5
6
7
8
9
10
11
int main()
{

	while (std::cin.peek() == EOF)
		std::cout << "waiting..\n";

	char ch;
	std::cin >> ch;

    return 0;
}
you can use a thread if the data from getline is not required to proceed.
then you can detect if you have read something and handle it, if not, keep going...
So basicly there is no way to do this in c++ with only 1 thread? I found this really weird. A lot of other programming languajes let you manage interruptions when this kind of slow and rare events happen (like user input for example)
Back in the days of 32 bit processors with only 1 thread surely they needed to overcome this in some way.
threads were used all the time way back on single core machines. They just run better on multicore machines. But we had them back on 2/3 86 generation machines, and used them. Windows 3.0 is a glaring example of an over-threaded monster. (I don't remember the 1.0 and 2.0 too well, 3.0 had a long long lifespan).

there may be other ways to do it. A thread is one way.
Peeking at the input stream is another, and it should work if you do it right.
Direct hardware traps would work as well (a bit less portable, but think directinput on windows).
There are probably a dozen ways to do this (like most problems). If threading isnt good for you, ignore my idea, it won't hurt my feelings :)

antique machines would probably have used the hardware trap, as they simply were almost always programmed to use the fastest thing going and that is the fastest way to deal with this problem.
Last edited on
The C++ I/O model is based around streams. With a simple input stream all you can do is read more data or know if you're at the end of the stream. Input from the console is taken via a stream as well, and asynchronous events such as the user pressing a key at some random moment simply cannot be modeled with streams.

If the stream abstraction doesn't work for you and you need to treat the console as a proper console then you should use one of the curses libraries (ncurses or PDcurses), which are designed to do just that.
Thanks jonnin and all who answered. I would look more into this ideas and see which one suits me best for this problem.
It is very much possible to do this, but it requires OS-specific code and is a general pain to deal with. Your best option is to restructure your design to avoid having to do this.

That said, I've written a little function to do it often enough:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <ciso646>
#include <iostream>
#include <string>

#ifdef _WIN32

  #ifndef NOMINMAX
  #define NOMINMAX
  #endif
  #include <windows.h>

  bool iskeypressed( unsigned timeout_ms = 0 )
  {
    return WaitForSingleObject(
      GetStdHandle( STD_INPUT_HANDLE ),
      timeout_ms
    ) == WAIT_OBJECT_0;
  }

#else // POSIX

  #include <poll.h>
  #include <termios.h>
  #include <unistd.h>

  bool iskeypressed( unsigned timeout_ms )
  {
    struct pollfd pls[ 1 ];
    pls[ 0 ].fd     = STDIN_FILENO;
    pls[ 0 ].events = POLLIN | POLLPRI;
    return poll( pls, 1, timeout_ms ) > 0;
  }

#endif

int main()
{
  while (!iskeypressed( 500 ))
    std::cout << "Enter your name...\n";

  std::string name;
  getline( std::cin, name );

  std::cout << "Hello " << name << "!\n";
}

There are a lot of caveats to this code which you are entirely unaware of. Go ahead and play with it. But make sure you get in contact with someone who knows what's going on before you consider anything for production. For personal stuff or homework, though, this should help.

Good luck!
Topic archived. No new replies allowed.