我试图在我的命令行应用程序中添加自动完成功能.到目前为止,所有答案都说它是shell的优先级,但在我的情况下它是不同的.我的程序进入循环(获取命令)main(),所以我认为它与shell无关.我怎样才能实现这样的目标?
以下是我的计划.当用户点击enter(std::getline())时,它开始解析.如何在不使用任何外部库的情况下在运行时获取用户输入?
while (input != "exit") {
std::cout << "\nCommand >> ";
std::getline(std::cin, input);
com.parse(input);
}
Run Code Online (Sandbox Code Playgroud) 在Windows上,我有以下代码来查找输入而不中断循环:
#include <conio.h>
#include <Windows.h>
#include <iostream>
int main()
{
while (true)
{
if (_kbhit())
{
if (_getch() == 'g')
{
std::cout << "You pressed G" << std::endl;
}
}
Sleep(500);
std::cout << "Running" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,看到没有conio.h,在Linux上实现这一点的最简单方法是什么?
有没有人有一段代码,不windows.h用于在while循环中检查按键.基本上这个代码,但不必使用windows.h它.我想在Linux和Windows上使用它.
#include <windows.h>
#include <iostream>
int main()
{
bool exit = false;
while(exit == false)
{
if (GetAsyncKeyState(VK_ESCAPE))
{
exit = true;
}
std::cout<<"press esc to exit! "<<std::endl;
}
std::cout<<"exited: "<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 因此,我有以下代码,该代码基本上只读取字符用户输入并打印它们,直到输入“ q”为止。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<termios.h>
int main(void) {
char c;
static struct termios oldtio, newtio;
tcgetattr(0, &oldtio);
newtio = oldtio;
newtio.c_lflag &= ~ICANON;
newtio.c_lflag &= ~ECHO;
tcsetattr(0, TCSANOW, &newtio);
printf("Give text: ");
fflush(stdout);
while (1) {
read(0, &c, 1);
printf("%c", c);
fflush(stdout);
if (c == 'q') { break; }
}
printf("\n");
tcsetattr(0, TCSANOW, &oldtio);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在主要功能的开头,我关闭规范模式,以使用户能够在输入时看到自己的输入。我还关闭了回声,例如在按下向上箭头键时不会弹出诸如“ ^ [[A””之类的信息。这行得通,但是我也可以将光标移到终端窗口的上排,这不好。有没有办法解决此问题,使用户只能在当前行内移动?
另一个问题是退格键。当我按下它时,程序将打印一个奇怪的符号(我假设它是0x7f),而不是擦除光标当前位置的剩余字符。我应该以某种方式适当地处理程序中的退格键输出,但是我不知道该怎么办,因为它是这个奇怪的十六进制数。有什么提示吗?
我也一直在考虑使这项工作可行的一种方法是使用规范模式,以便自动使用箭头键和退格功能。但是,规范模式逐行工作,因此直到用户单击“ Enter”后,文本才会出现。到目前为止,我还没有找到让用户在键入时看到其输入的任何方法。这有可能吗?
而且,请不要提出任何疑问或阅读建议。我想使用termios.h做到这一点。
我想在 OS X 上的命令行应用程序中执行以下操作:
while (true) {
// do some task
if (user_has_pressed('x')) {
// break out of the loop and do something different
}
}
Run Code Online (Sandbox Code Playgroud)
为清楚起见,我不希望程序阻塞等待用户输入。我正在运行一个需要很多小时才能运行的数值模拟,我想按一个键来打印有关其进度的详细统计信息,或者中断它并更改参数等。
有一些现有的类似 问题,但答案要么建议仅使用 Windowsgetch功能,要么将终端切换到不同的输入模式。我不想这样做,因为我需要保留在ctrl-c不弄乱终端的情况下中断的能力。
我不想构建 Cocoa 应用程序,也不关心跨平台。我只是在寻找一种最简单快捷的方法来在一个只能在我自己的机器上运行的命令行应用程序中完成它。
我想一种选择是使用 ncurses。从简短的阅读来看,这似乎是一个比我想要的更重的选择 - 但是如果有人会发布一个简单的最小示例来完成上述任务,那将非常有帮助。
我不知道如何在中间停止程序有人可以帮助我我希望我的程序停止定义的秒数,例如 3 秒或 6 秒,如果您按任意键,它会立即开始运行。
这是C编程语言中的一个问题.
如何直接读取键盘缓冲区中的数据?
我想直接访问数据并将其存储在变量中.变量应该是什么数据类型?
我需要它用于我们研究所正在开发的操作系统.它被称为ICS-OS,我不太确定具体细节.它运行在x86,32位机器上(我们在Linux机箱中的QEMU上运行).以下是Google Code http://code.google.com/p/ics-os/的链接.我希望这些信息足够充分.
操作系统不支持conio.h库,因此kbhit不是一个选项.
我目前正在为linux设计CLI界面,由于各种原因,我无法使用ncurses.我只使用C++和Qt框架.
因此,为了拥有一个用户友好的界面,我必须在一个单独的线程中运行这个getch循环:
这基本上意味着我必须自己实现所有基本功能(例如退格).我已经实现了命令完成和命令历史记录(比如当你在linux中按tab或uparrow/downarrow时),但我无法弄清楚如何实现leftarrow/rightarrow(也就是通过typeahead寻找).
通常情况下,我这样实现:在每个不等于-1的gech上,我检查用户是否按下了一个特殊的键(一个以某种方式修改了typeahead的键).然后我使用以下函数清除stdout:
void inputobject::clear_line(int nletters)
{
QTextStream(stdout) << "\033[2K";
for(int i = 0; i < nletters;i++){
QTextStream(stdout) << "\b";
}
rewind(stdout);
}
Run Code Online (Sandbox Code Playgroud)
并用其他东西替换它,有效地模拟typeahead.例如,在退格的情况下,我会保存命令调用clear_line,并再次打印命令,只需少一个字母,行为与普通控制台应用程序完全相同.
我真正的问题是光标,在左/右箭头的情况下,我需要移动光标可视化,以便能够指示文本在用户寻找的位置:
由于我如何重写给定的stdout线以模拟typeahead的性质,光标REALLY的位置并不重要,只要它保持在同一条线上 - 它只是重要的视觉效果.如何在linux上实现移动光标可视化?
我正在尝试编写一个简单的小代码片段来响应箭头按键.我知道up由^ [[A表示,我有以下代码检查该序列:
while( 1 )
{
input_char = fgetc( stdin );
if( input_char == EOF || input_char == '\n' )
{
break;
}
/* Escape sequence */
if( input_char == 27 )
{
input_char = getc( stdin );
if( input_char == '[' )
{
switch( getc( stdin ) )
{
case 'A':
printf("Move up\n");
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
每当我点击"向上"时,转义序列(^ [[A]显示在屏幕上,但"上移"直到我按下回车才出现.
最终目标是用其他一些数据替换当前行上的文本,所以我试着这样做
printf("\r%s", "New Text");
Run Code Online (Sandbox Code Playgroud)
取代"向上移动",但在按下输入后仍然不会显示.
我在读字的方式有问题吗?
谢谢!
编辑快速注释,它适用于*nix系统.
解决方案 感谢大家的指点.我选择了stepanbujnak的解决方案,因为它非常简单.我注意到的一件事是修改字符串(退格等)的键的很多行为与你期望的不同.它会在线上退出任何东西(包括printf'd的东西),我不得不考虑到这一点.在那之后,让其他人排成一行并不太糟糕:)