9 Replies - 1042 Views - Last Post: 04 September 2016 - 12:05 PM Rate Topic: -----

#1 kekie  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 10-July 14

User interupts program output C++

Posted 03 September 2016 - 01:39 PM

I have written a program that gets user input with getline(), and then prints some information to the terminal with several std::cout's, with some delay in-between pieces of data. However, if the user types while the output is being printed to the screen, whatever they type will appear, spliced into the output in a very ugly way. (I don't think that the getline() actually has anything to do with this problem, but I thought I'd mention it just in case it does.)

Is there some way to stop user input from being written to the screen, while still using the terminal (I don't want to write a GUI)?

Is This A Good Question/Topic? 0
  • +

Replies To: User interupts program output C++

#2 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6403
  • View blog
  • Posts: 25,878
  • Joined: 12-December 12

Re: User interupts program output C++

Posted 03 September 2016 - 02:21 PM

Post some relevant code so people can see what you are referring to.
Was This Post Helpful? 1
  • +
  • -

#3 kekie  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 10-July 14

Re: User interupts program output C++

Posted 03 September 2016 - 03:23 PM

#include <iostream>
#include <unistd.h>
int main()
{
    std::string input;

    while(true)
    {
        std::getline(std::cin,input);
        std::cout<<"output1"<<std::endl;
        usleep(200000);
        std::cout<<"output2"<<std::endl;
        usleep(200000);
        std::cout<<"output3"<<std::endl;
        usleep(200000);
    }

    return 0;
}



If I type "hello", and then press enter I get:
hello
output1
output2
output3

If I type "hello", press enter, and press the a key several times I get something like:
hello
output1
aaoutput2
aoutput3

This problem seems to only be on linux (I'm running xubuntu).
Was This Post Helpful? 0
  • +
  • -

#4 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6403
  • View blog
  • Posts: 25,878
  • Joined: 12-December 12

Re: User interupts program output C++

Posted 03 September 2016 - 05:57 PM

You are running MS CLI C++ on Linux?

Note that, usleep:

Quote

POSIX.1-2001 declares this function obsolete;
use nanosleep(2) instead. POSIX.1-2008 removes the specification of
usleep().

I cannot help you myself with anything Linux-y, you'll have to wait for someone else ;)
Was This Post Helpful? 0
  • +
  • -

#5 kekie  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 10-July 14

Re: User interupts program output C++

Posted 03 September 2016 - 06:39 PM

View Postandrewsw, on 03 September 2016 - 05:57 PM, said:

You are running MS CLI C++ on Linux?


Oh oooooops. I posted this in the wrong sub-fourum. I hate to bother you, but since you're a mod, would you mind moving this to the main "C and C++" forum?

This post has been edited by kekie: 03 September 2016 - 06:40 PM

Was This Post Helpful? 0
  • +
  • -

#6 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6403
  • View blog
  • Posts: 25,878
  • Joined: 12-December 12

Re: User interupts program output C++

Posted 03 September 2016 - 06:43 PM

Topic moved out of CLI.
Was This Post Helpful? 1
  • +
  • -

#7 kekie  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 10-July 14

Re: User interupts program output C++

Posted 03 September 2016 - 06:51 PM

View Postandrewsw, on 03 September 2016 - 06:43 PM, said:

Topic moved out of CLI.


Thank you!

I tried nanosleep, and I had the same problem.
#include <iostream>
#include <unistd.h>
int main()
{
    std::string input;
    timespec* interval= new timespec;
    interval->tv_sec=1;

    while(true)
    {
        std::getline(std::cin,input);
        std::cout<<"output1"<<std::endl;
        nanosleep(interval,interval);
        std::cout<<"output2"<<std::endl;
        nanosleep(interval,interval);
        std::cout<<"output3"<<std::endl;
        nanosleep(interval,interval);
    }

    return 0;
}

(I think I'm using nanosleep correctly..? It appears to work.)
Was This Post Helpful? 0
  • +
  • -

#8 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6403
  • View blog
  • Posts: 25,878
  • Joined: 12-December 12

Re: User interupts program output C++

Posted 03 September 2016 - 11:45 PM

I think that is what as known as expected behaviour. nanosleep (et al):

Quote

nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed, or the delivery of a signal that triggers the invocation of a handler in the calling thread or that terminates the process.

If the call is interrupted by a signal handler, nanosleep() returns -1, sets errno to EINTR

As I say, I'm not a Linux person, but:

Linux - Discard keyboard input:

Quote

Turn off echo mode with stty -echo or the equivalent C code (which would use tcgetattr and tcsetattr). When you are ready to accept input again, turn it back on. You may also wish to discard the input that arrived while you weren't expecting it. That would be done with tcflush but be aware that some users (like me) would consider that an annoyance. Typeahead is a feature, not a bug!

So you might try disabling echo before sleeping, then flush the terminal buffer.

Or take a more pragmatic approach and say "why would anyone be typing?" (or even, why does a terminal need to sleep? ;) )
Was This Post Helpful? 1
  • +
  • -

#9 kekie  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 31
  • Joined: 10-July 14

Re: User interupts program output C++

Posted 04 September 2016 - 11:54 AM

Yes! That seems to have worked.
#include <iostream>
#include <unistd.h>
#include <termios.h>
int main()
{
    std::string input;
    timespec* interval= new timespec;
    interval->tv_sec=1;

    termios t_echo;
    termios t_noecho;
    tcgetattr(0,&t_noecho);
    tcgetattr(0,&t_echo);

    t_noecho.c_lflag&= ~ECHO;

    while(true)
    {
        std::getline(std::cin,input);
        tcsetattr(0,TCSANOW,&t_noecho);
        std::cout<<input<<std::endl;

        std::cout<<"output1"<<std::endl;
        nanosleep(interval,interval);
        std::cout<<"output2"<<std::endl;
        nanosleep(interval,interval);
        std::cout<<"output3"<<std::endl;
        nanosleep(interval,interval);

        tcflush(0,TCIFLUSH);
        tcsetattr(0,TCSANOW,&t_echo);

    }

    return 0;
}


Though I'm not sure if this is the most elegant way of doing this. I'm pretty inexperienced with all this linux stuff as well.

This post has been edited by kekie: 04 September 2016 - 11:55 AM

Was This Post Helpful? 1
  • +
  • -

#10 andrewsw  Icon User is offline

  • say what now
  • member icon

Reputation: 6403
  • View blog
  • Posts: 25,878
  • Joined: 12-December 12

Re: User interupts program output C++

Posted 04 September 2016 - 12:05 PM

You are forcing unnatural behaviour on the terminal, it's never going to be pretty.

I couldn't tell you whether there is anything more elegant you could do with that code, but glad it is a solution.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1