1

I am trying to find a way to have the input stop without the need to press Enter when user inputs the delimiting character in getline function in my practice application.

Currently the input stream from getline is only interrupted if user presses Enter after typing in delimiting character and the cout message explains it to the user but preferably I would prefer for input to simply stop when delimiter is pressed.

Looking for suggestions on how I could stop the input when it detects a specified character.

Here is full code I have :

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

#define DEBUG 1 // 1 = enabled

int main()
{
    char takeFirstNonSpaceCharacter(string text);
    string message;
    char stopper;
    string stopperInput;

    cout << "Type the character with which you want to signal end of a message\n";
    cin >> stopperInput;
    cin.ignore(128, '\n'); //clean cin

    stopper = takeFirstNonSpaceCharacter(stopperInput); //in case input has white spaces
    cout << "Type your message, make it as long as you want.\n To finish typing enter the " << stopper << " symbol followed by Enter\n Input after the " << stopper << " symbol will be lost\n";

    getline(cin, message, stopper);
#if DEBUG == 1
    cout << message << '\n';
#endif
    system("pause");
    return 0;
}

char takeFirstNonSpaceCharacter(string text)
{
    string::const_iterator iter = text.begin();
    while (iter != text.end())
    {
        if (*iter != 32 || *iter != 10 || *iter != 9) //ascii: 32 = space, 10 = new line, 9 = horizontal tab
        {
            return *iter; //if its not space character then it must be a character (unless the user can somehow type for example \0 on keyboard)
        }
        else
        {
            iter++; //if its space
        }
    }
    return '\0';
}

With the input/output being around this (bold is my input)

Type the character with which you want to signal end of a message

}

Type your message, make it as long as you want. To finish typing enter the } symbol followed by Enter Input after the } symbol will be lost

asdf}asdf

asdf

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35

1 Answers1

2

With standard-c/c++, you won't be able to access the consoles input until the user sends it with enter. The only way is to access the terminal directly, but since every OS uses different consoles, it requires OS-specific solutions.

On windows you can do this with <conio.h>'s _getch() or with WinApi ReadConsoleInput.

On unix you can use <termios.h> or <curses.h>

Crossplattform libraries, which work on every OS:
NCurses

synchronet ciolib

PDcurses

Here's a code example for windows:

#include <conio.h>      // _getch()
#include <cctype>       // std::isspace
#include <string>       // std::getline
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if_not

#define DEBUG

int main(void)
{
    int stopper;

    std::cout << "Type the character with which you want to signal end of a message" << std::endl;

    while (std::isspace(stopper = std::cin.get())) {} // oneliner instead of takeFirstNonSpaceCharacter
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // flush the rest of 

    // alternative oneliner without the need of pressing enter
    // do { stopper = _getch(); } while (std::isspace(stopper));

    std::cout << "Type your message, make it as long as you want." << std::endl;
    std::cout << "To finish typing, enter the " << (char)stopper << " symbol followed by Enter" << std::endl;
    std::cout << "Input after the " << (char)stopper << " symbol will be lost" << std::endl;

    std::string message;
    for(int ch = _getch(); ch != stopper; ch = _getch()) {
        _putch(ch); // print it, so the user can see his input
        message.push_back(ch); // concat it to the message buffer
    };

#ifdef DEBUG
    std::cout << std::endl << message << std::endl;
#endif
    getchar(); // system("pause"); is windows only, don't use that!
    return 0;
}

Notes:

5andr0
  • 1,578
  • 1
  • 18
  • 25