4

when reading from std::cin even if I want to read only one char. It will wait for the user to insert any number of chars and hit Enter to continue !

I want to read char by char and do some instructions for every char while the user is typing in the terminal.

Example

if I run this program and type abcd then Enter the result will be

abcd
abcd

But I want it to be :

aabbccdd

Here is the code :

int main(){
    char a;
    cin >> noskipws >> a;
    while(a != '\n'){
        cout << a;
        cin >> noskipws >> a;
    }
}

How to do that please ?

webNeat
  • 2,768
  • 1
  • 20
  • 22

5 Answers5

9

The best way to read single characters from a stream in a C++-friendly way is to get the underlying streambuf and use the sgetc()/sbumpc() methods on it. However, if cin is supplied by a terminal (the typical case) then the terminal likely has line buffering enabled, so first you need to set the terminal settings to disable line buffering. The example below also disables echoing of the characters as they are typed.

#include <iostream>     // cout, cin, streambuf, hex, endl, sgetc, sbumpc
#include <iomanip>      // setw, setfill
#include <fstream>      // fstream

// These inclusions required to set terminal mode.
#include <termios.h>    // struct termios, tcgetattr(), tcsetattr()
#include <stdio.h>      // perror(), stderr, stdin, fileno()

using namespace std;

int main(int argc, const char *argv[])
{
    struct termios t;
    struct termios t_saved;

    // Set terminal to single character mode.
    tcgetattr(fileno(stdin), &t);
    t_saved = t;
    t.c_lflag &= (~ICANON & ~ECHO);
    t.c_cc[VTIME] = 0;
    t.c_cc[VMIN] = 1;
    if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0) {
        perror("Unable to set terminal to single character mode");
        return -1;
    }

    // Read single characters from cin.
    std::streambuf *pbuf = cin.rdbuf();
    bool done = false;
    while (!done) {
        cout << "Enter an character (or esc to quit): " << endl;
        char c;
        if (pbuf->sgetc() == EOF) done = true;
        c = pbuf->sbumpc();
        if (c == 0x1b) {
            done = true;
        } else {
            cout << "You entered character 0x" << setw(2) << setfill('0') << hex << int(c) << "'" << endl;
        }
    }

    // Restore terminal mode.
    if (tcsetattr(fileno(stdin), TCSANOW, &t_saved) < 0) {
        perror("Unable to restore terminal mode");
        return -1;
    }

    return 0;
}
bleater
  • 5,098
  • 50
  • 48
7

The C++ cin model is that the user composes an entire line in the terminal, backspacing and correcting if necessary, then when he is happy, submits the whole line to the program.

You can't easily break that, nor should you, unless you want to take over the entire terminal and, for example, have a little man wandering about a maze controlled by keypresses. To do that use curses.h on Unix systems or conio.h on DOS systems.

Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
  • 1
    +1 for the little man :) (and because it's all correct). But I really should've also -1'ed it, too, for that "DOS systems", since the answer date is apparently 2017, not 1997. ;-p – Sz. Jul 14 '19 at 21:57
0

i think you should write a struct by yourself. Like me, i use

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

using namespace std;

char get_char(){
    int k;
    int i = 0;
    while(i == 0){
        if(kbhit()){
            k = _getch();
            i++;
        }
    }
    return char(k);
}

int main(){
    char minhvu[10];
    for(int i = 0; i < 10; i++){
        minhvu[i] =  get_char();
        cout << minhvu[i];
    }
}

but this have a weakness that i must write it correctly and can not to delete and rewrite like using cin

Vu Minh
  • 1
  • 1
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 06 '23 at 00:59
-1

Take a look at:

std::cin.get(char)
Evgeny Sobolev
  • 515
  • 4
  • 13
-2
#include <iostream>
#include <conio.h>
using namespace std;

int main()
{
    char a;
    do{
        a=getche();
        cout<<a;
    }while(a!='\n');
    return 0;
}