当用户键入分隔符时停止 getline() 输入
Stop getline() input when user types delimiter character
我正在尝试找到一种方法,当用户在我的练习应用程序中的 getline 函数中输入定界字符时,无需按 Enter 即可停止输入。
目前,只有当用户在输入定界字符后按下 Enter 时,来自 getline 的输入流才会中断,并且 cout 消息会向用户解释,但我更希望输入在按下定界符时简单地停止。
正在寻找有关如何在检测到指定字符时停止输入的建议。
这是我的完整代码:
#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 [=10=] on keyboard)
}
else
{
iter++; //if its space
}
}
return '[=10=]';
}
input/output 围绕这个(粗体是我的输入)
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
使用 standard-c/c++,您将无法访问控制台输入,直到用户使用 enter 发送它。唯一的方法是直接访问终端,但由于每个 OS 使用不同的控制台,因此需要 OS 特定的解决方案。
在 windows 上,您可以使用 <conio.h>
的 _getch()
或 WinApi ReadConsoleInput
.
在 unix 上你可以使用 <termios.h>
或 <curses.h>
Crossplattform 库,适用于每个 OS:
NCurses
这是 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;
}
备注:
- 如果您是 c++ 新手,请尽量避免使用
using namespace std;
并习惯 std::
前缀
Why is "using namespace std;" considered bad practice?
- 不要使用
system("pause");
system("pause"); - Why is it wrong?
- 如果仅用于布尔值,请不要为宏使用值。你可以使用
#ifdef DEBUG
如果你不想使用它就不要定义 DEBUG
- std::isspace 可以替换你的 takeFirstNonSpaceCharacter 函数
- 将长行拆分为多行以提高可读性
我正在尝试找到一种方法,当用户在我的练习应用程序中的 getline 函数中输入定界字符时,无需按 Enter 即可停止输入。
目前,只有当用户在输入定界字符后按下 Enter 时,来自 getline 的输入流才会中断,并且 cout 消息会向用户解释,但我更希望输入在按下定界符时简单地停止。
正在寻找有关如何在检测到指定字符时停止输入的建议。
这是我的完整代码:
#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 [=10=] on keyboard)
}
else
{
iter++; //if its space
}
}
return '[=10=]';
}
input/output 围绕这个(粗体是我的输入)
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
使用 standard-c/c++,您将无法访问控制台输入,直到用户使用 enter 发送它。唯一的方法是直接访问终端,但由于每个 OS 使用不同的控制台,因此需要 OS 特定的解决方案。
在 windows 上,您可以使用 <conio.h>
的 _getch()
或 WinApi ReadConsoleInput
.
在 unix 上你可以使用 <termios.h>
或 <curses.h>
Crossplattform 库,适用于每个 OS:
NCurses
这是 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;
}
备注:
- 如果您是 c++ 新手,请尽量避免使用
using namespace std;
并习惯std::
前缀
Why is "using namespace std;" considered bad practice? - 不要使用
system("pause");
system("pause"); - Why is it wrong? - 如果仅用于布尔值,请不要为宏使用值。你可以使用
#ifdef DEBUG
如果你不想使用它就不要定义 DEBUG - std::isspace 可以替换你的 takeFirstNonSpaceCharacter 函数
- 将长行拆分为多行以提高可读性