Thread: getch() and other oddities

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    153

    getch() and other oddities

    Hye everyone,
    So check this out...I have this code, I know it doesnt do anything...it's for test purposes:
    Code:
    cout << "What is your name?";
    char ch = getch();
    while (ch != '\r')
    {
       if (ch >= '0' && ch <= '9')
       {  
           cout << ch;
       }
       
       ch = getch();
    }
    So what this does is basically only allows the user to enter numbers...but a few questions arise...due to the restrictions of this, the ability to delete is cut off...I tried testing for ch == '\b' but that only went back a space everytime I hit delete...not exactly helpful...any creative solutions around this?...I searched online for a while and didnt find any escape sequence that would mean a delete...I was actually surprised by that.


    Ok so there's that...and then there's this...so using my backspacing I was able to start overwriting the string literal "What is your name?"...so now my question is does that affect your program at all? I mean I'm not exactly sure what is happening with backspacing on top of already printed to the screen characters...so...any insight into whether only aesthetic issues arise or if I'm tapping into anything bad...I dunno...just curious...sorry if I'm not making myself clear, any help would be the *expletive deleted for the sake of all readers* -Chap

  2. #2
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Overwriting "What is your name?" is not overwriting the string literal It has already been 'written' to the console window, i.e. copied somewhere internally to some block of console memory or something. Basically, the memory you're overwriting is a copy of the string literal, and it's meant to be modified anyway.

    About backspacing, if you can figure out what character to test for to move back one space (does '\b' work?), you can just write code that backspaces 1 place, writes a ' ' character, and backspaces again, whenever you come across that character.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    153
    About backspacing, if you can figure out what character to test for to move back one space (does '\b' work?), you can just write code that backspaces 1 place, writes a ' ' character, and backspaces again, whenever you come across that character.
    Hunter you're right...jesus...I'm such an idiot! Why the hell didnt I think of that...I think I jumped too quickly into the mentality of "I need to get an answer to this or my head will explode!!"...arg...

    Overwriting "What is your name?" is not overwriting the string literal
    I must apologize...my choice of wording was foolish, I meant overwriting in an aesthetic sense...although you did bring up a cool point about how all we're looking at is a literal that's meant to be modified, I never really looked at it like that, thanks for the shift of perspective...but now...when I backspace over this literal thats been printed to the screen...is there actual memory that's being overwritten? Even if its the memory of the copy...memory is still being overwritten? I thought it was just printing the character because I told it to and there was no real internal anything going on...

    One last thing...if getch() returns a single character...is it possible to prevent \b from going past the starting point of input...I mean, can I test for an element index of any kind?
    Questions questions everywhere!!

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    To stop you backspacing too far, just keep a count of how many characters have been entered, and only allow the user to delete that many.

    You should also <<flush the string out to force it to the screen.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    153
    what do you mean by <<flush? curiously...

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    cout<<"your message here" <<flush;

    http://www.cppreference.com/cppio/flush.html
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    Registered User
    Join Date
    Sep 2004
    Posts
    153
    on an unrelated note...I like how you can start off with simple enough code and then as you enter more capabilities and start factoring in how a user is going to handle your program, you start to develop these more complex chunks of code...what started off with a simple while statement testing one if inside has now turned into nested ifs within a while...I dunno...just thought it was cool, the beauty of being a beginner

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>there was no real internal anything going on...
    This may be possible, but it's unlikely - otherwise, how does the console know what to re-draw and what not to? And when you use std::cin, the cursor moves back and forth and whatnot. Granted, it could just be a bitmap image of the whole console window that gets stored, but that isn't super memory-efficient (takes about 25+ times as much storage by my reckoning) so it's unlikely.

    >>what do you mean by <<flush? curiously...
    Code:
    std::cout << "Hello! Part of this message might not be output to the screen!";
    Or, you could do:
    Code:
    std::cout << "Hello! All of this message has been output to the screen!" << std::flush;
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    If you're interested, there's a C implementation of something similar here:
    http://faq.cprogramming.com/cgi-bin/...&id=1043284392
    (second lot of code)
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    Registered User
    Join Date
    Sep 2004
    Posts
    153
    Code:
    std::cout << "Hello! Part of this message might not be output to the screen!";
    Interesting, what factors could potentially stop this from being output?

    I havent come across flush up until now so I'm trying to get as much info now, should flush solely be used for debugging purposes? Sorry I'm full of questions haha...I'm a curious mofo...

  11. #11
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>should flush solely be used for debugging purposes?
    No. When you cout text, it is written to an output buffer, you should flush that buffer if you want to guarantee that the text is written to its destination (the screen in this case).

    The problem is particularly noticable when using cout for debugging (as highlighted), but can also happen under normal running conditions as well.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  12. #12
    Registered User
    Join Date
    Sep 2004
    Posts
    153
    ok...any particular examples of what would cause the output buffer to withhold some of its contents? this is all very interesting...

  13. #13
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Can't say I've ever run into it, but that shouldn't deter you from adding flush or endl - after all, things might work differently on another platform.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  14. #14
    Registered User Scribbler's Avatar
    Join Date
    Sep 2004
    Location
    Aurora CO
    Posts
    266
    Quote Originally Posted by Chaplin27
    ok...any particular examples of what would cause the output buffer to withhold some of its contents? this is all very interesting...
    Typically the output buffer doesn't flush unless a newline character is sent, the program is waiting for input, or it's forced to flush.

    Here's an example where the output doesn't flush when you'd expect it to. Timer 1 doesn't flush until it's complete, and Timer 2 flushes at each tick.
    Code:
    #include <iostream>
    #include <ctime>
    using namespace std;
    
    #define TIMER 10
    
    void timer1();
    void timer2();
    
    int main ()
    {
    	timer1();
    	timer2();
    	
    	return 0;
    }
    
    void timer1()
    {
    	int tick = 0;
    	clock_t delay = CLOCKS_PER_SEC * TIMER;
    	clock_t start = clock();
    	
    	cout << "Timer one:" << endl;
    	
    	while ( clock() - start <= delay )
    	{
    		if ( ( clock() - start ) / CLOCKS_PER_SEC > tick)
    			cout << ++tick;
    	}
    	cout << endl << endl;
    }
    
    void timer2()
    {
    	int tick = 0;
    	int delay = TIMER;
    	int start = time(0);
    	
    	cout << "Timer two:" << endl;
    	
    	while ( start + TIMER > time(0) )
    	{
    		if ( time(0) - tick > start )
    			cout << ++tick << endl;
    	}
    }

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    What's the difference between:

    cout<<"some string"<<flush();

    and

    cout<<"some string"<<endl;

    EDIT ***
    Found the answer:
    endl enters a newline character and then flushes.
    Last edited by 7stud; 02-17-2005 at 10:37 AM.

Popular pages Recent additions subscribe to a feed