3

I hope the question isn't to ambiguous.

when I ask:

int main()
{

string name = {""};

cout << "Please enter a name: " << endl;
getline(cin, name);
//user enters 12 characters stop displaying next literal keypresses.
enter code here
}

I would like to be able to limit the amount of times the user can enter a char on screen. Example, the screen stops displaying characters after length 12?

If so what would be the library and command line for doing something like this?

Wanting to this as, I have a ascii art drawn on the CMD, and when I cout the statement at x,y anything over 12 characters long inputed draws over the ascii art.

I hope this makes sense :'{ Thank you!

Cameron P
  • 57
  • 6

3 Answers3

9

By default the console is in cooked mode (canonical mode, line mode, ...). This means

  1. that the console driver is buffering data before it hands it to your application
  2. characters will be automatically echoed back to the console by the console driver

Normally, this means that your program only ever gets hold of the input after a line ends, i.e. when enter is pressed. Because of the auto-echo, those character are then already on screen.

Both settings can be changed independently, however the mechanism is --unfortunately-- an OS-specific call:

For Window it's SetConsoleMode():

HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE); 
DWORD mode = 0;

// get chars immediately
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~ENABLE_LINE_INPUT));


// display input echo, set after 12th char.
GetConsoleMode(hStdin, &mode);
SetConsoleMode(hStdin, mode & ~ENABLE_ECHO_INPUT));

As noted by yourself, Windows still provides conio.h including a non-echoing _getch() (with underscore, nowadays). You can always use that and manually echo the characters. _getch() simply wraps the console line mode on/off, echo on/off switch into a function.

Edit: There is meant to be an example on the use of _getch(), here. I'm a little to busy to get it done properly, I refrained from posting potentially buggy code.

Under *nix you will most likely want to use curses/termcap/terminfo. If you want a leaner approach, the low level routines are documented in termios/tty_ioctl:

#include <sys/types.h>
#include <termios.h>

struct termios tcattr;

// enable non-canonical mode, get raw chars as they are generated
tcgetattr(STDIN_FILENO, &tcattr);
tcattr.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcattr);

// disable echo
tcgetattr(STDIN_FILENO, &tcattr);
tcattr.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcattr);
dhke
  • 15,008
  • 2
  • 39
  • 56
  • I see so by wrapping, //disable echo in an if statement, I should be able to set parameters to stop echo'ing at a certain point. I did manage to use a _getch() then add concatenate it with an empty string, and had a handler to repeat _getch() untill ENTER was recieved. Will post non-canonical method if I manage to work it in :) Thank you so much – Cameron P Sep 01 '15 at 08:21
  • Yeah, I almost forgot that [`conio.h`](https://msdn.microsoft.com/en-us/library/7x2hy4cx.aspx) still exists. Since `_getch()` does not echo, you can always echo the chars manually. – dhke Sep 01 '15 at 08:26
0

You can use scanf("%c",&character) on a loop from 1 to 12 and append them to a pre-allocated buffer.

Catalin
  • 474
  • 4
  • 19
0

As in my comments, I mentioned a method I figured out using _getch(); and displaying each char manually.

simplified version:

#include <iostream>
#include <string>
#include <conio.h>

using namespace std;
string name = "";


int main() 
{
    char temp;
    cout << "Enter a string: ";
    for (int i = 0; i < 12; i++) { //Replace 12 with character limit you want
        temp = _getch();
        name += temp;
        cout << temp;
    }
    system("PAUSE");
}

This lets you cout each key-press as its pressed, while concatenating each character pressed to a string called name.

Then later on in what ever program you use this in, you can display the full name as a single string type.

Cameron P
  • 57
  • 6
  • You can also inject handlers for certain key-pressed just after the for loop statement to catch certain illegal key presses. You can also, have an if statement nested into the for loop to say, if i >11 temp = null; so, it wont cout anything. Much like most text fields for entering a username. – Cameron P Sep 03 '15 at 06:59