1

my problem is trying to go to the next instruction without pressing enter.. this is my code

cout<<"Enter Date Of Birth: ";
cin>>day;
cout<<"/";
cin>>month;
cout<<"/";
cin>>year;

by only providing 2 digit number for day, i want the next instruction to get printed without me pressing enter, and so goes to the rest month and year. since year is the last, i can press enter after that.

louie
  • 13
  • 3

4 Answers4

1

You could write a function like this:

#include <iostream>
#include <sstream>
#include <conio.h>
#include <vector>
#include <math.h>

int getInput(int count)
{
    int i = 0;
    std::stringstream ss;

    while (count)
    {
        char c = _getch();
        std::cout << c;
        ss << c;
        count--;
    }

    ss >> i;
    return i;
}

int getInput_(int count)
{
    int num = 0;

    std::vector <int> v;

    while (count)
    {
        char c = _getch();
        std::cout << c;
        v.push_back(atoi(&c));
        count--;
    }

    for (size_t i = 0; i < v.size(); i++)
    {
        num += (int)(v[i] * (pow((float)10, (float)(v.size()-1)-i)));
    }

    return num;
}

int main()
{
    int day = 0, month = 0, year = 0;

    day = getInput_(2);

    std::cout << "/";

    month = getInput_(2);

    std::cout << "/";

    year = getInput_(4);

    std::cout << std::endl << day << "/" << month << "/" << year;
}
cpx
  • 17,009
  • 20
  • 87
  • 142
  • thank you very much dave, thats what i was looking for. but is there another function beside _getch that i can use, for a string maybe. so there is not need to use stringstream. – louie Dec 24 '10 at 18:31
  • Well there's no current standard input way that I could think of but you still could do it without using stringstream and replacing it with an array of int. – cpx Dec 24 '10 at 19:47
1

That's not possible portably in pure C++, because it depends too much on the terminal used that may be connected with stdin (they are usually line buffered). You can, however use a library for that:

  1. conio available with windows compilers. Use the function _getch() to give you a character without waiting for the enter key. I'm not a frequent windows developer, but i've seen my classmates just include conio.h and use it. See conio.h at wikipedia. It lists getch, which is declared deprecated in Visual C++.
  2. curses available for linux, compatible curses implementations are available for windows too. It has also a getch function. (try man getch to view its manpage). See Curses at wikipedia.

I would recommend you to use curses if you aim for cross platform compatibility. That said, I'm sure there are functions that you can use to switch off line buffering (i believe that's called "raw mode", as opposed to "cooked mode" (look into man stty)). Curses would handle that for you in a portable manner if i'm not mistaken.

THE DOCTOR
  • 4,399
  • 10
  • 43
  • 64
0

You need to do two things.

One, use input functions that operate on counted numbers of characters instead of whitespace separators. This rules out all stream extraction operators, you can't use cin >> anything.

Then, change your terminal mode from "cooked" to "raw". While the terminal is in cooked mode, no characters are delivered to your program until enter is pressed. The method for doing this depends on your OS, which you haven't told us. Note that this will also stop the terminal from processing editing keys such as backspace for you, so if you want to support them you'll have to code that logic yourself.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
0

For linux, the below code does what you want (reference this SO thread which you should read Capture characters from standard input without waiting for enter to be pressed ):

#include <iostream>
#include <fstream>    
#include <stdio.h>
#include <termios.h>
using namespace std;


char getch(void) {
    char buf = 0;
    struct termios old = {0};
    if (tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
    old.c_lflag &= ~ICANON;
    old.c_lflag &= ~ECHO;
    old.c_cc[VMIN] = 1;
    old.c_cc[VTIME] = 0;
    if (tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
    if (read(0, &buf, 1) < 0)
        perror ("read()");
    old.c_lflag |= ICANON;
    old.c_lflag |= ECHO;
    if (tcsetattr(0, TCSADRAIN, &old) < 0)
        perror ("tcsetattr ~ICANON");
    return (buf);
}

void readn(char *data, int N) {
    for(int ii = 0; ii < N; ii++) { data[ii] = getch(); cout << data[ii]; cout.flush(); };
};

int main () {
    char day[2], month[2], year[4];

    cout<<"Enter Date Of Birth: "; cout.flush();
    readn(day, 2); cout << "/"; cout.flush();
    readn(month, 2); cout << "/"; cout.flush();
    readn(year, 4); cout << endl; cout.flush();
}
Community
  • 1
  • 1
  • If you don't turn off echoing in the `getch` function (line `old.c_lflag &= ~ECHO;` ), then those cout.flush() are not necessary. –  Dec 24 '10 at 05:16
  • thank you so much for ur help JP19.. the problem with ur code is that it's long and kinda of complicated.. nvm i understood wat u were trying to say, thank you very much – louie Dec 24 '10 at 18:33