2013-03-29 80 views
-1

为了更好地熟悉C++,我重做了一个旧的大学OS作业:编写自己的shell。我处理的第一件事是接受命令,但我的方法留下了一些需要的功能。下面是我有:正确的字符输入?

string GetLine() { 
    string line; 
    char input = _getch(); 
    while (input != 13) { 
     switch (input) { 
     case 8: // backspace 
      if (line.length() != 0) { 
       line = line.substr(0, line.length() - 1); 
       cout << "\b \b"; 
      } 
      break; 
     case -32: // all arrows' first byte 
      input = _getch(); // distinctly different arrow byte 
      switch (input) { 
       case 72: // up 
        break; 
       case 80: // down 
        break; 
       case 75: // left 
        break; 
       case 77: // right 
        break; 
      } 
      break; 
     case 9: // tab 
      break; 
     default: 
      line += input; 
      cout << input; 
      break; 
     } 
     input = _getch(); 
    } 
    cout << endl; 
    return line; 
} 

它工作得很好,我知道我有更多的是用箭头键(如果我连他们区分正确的是)。我所问的主要问题是某些情况,光标已经缠绕到终端上的下一行。旨在模拟cmd.exe我打印提示,并在其末尾等待用户的输入。当这个提示很长时,只需要几个字符,然后我的命令在两行之间运行。如果我只是输入它,让它环绕并按输入一切工作正常。如果我换行到第二行并想退回到第一行,光标会停在新行的第一个字符处,并且不会像我希望的那样“打开”回第一行。我可以在这里做什么来实现这种展开行为?

我认为问题是试图打印'\ b'不会打开,但我没有一个替代方案的想法,我希望我不必把这作为一个特例并且将在行的中间退格的代码也将在行的开头起作用。

+0

您是否有能力使用libreadline?这样可以在处理这件事时为你节省很多心痛,并且有一整套技巧(如命令历史等) –

回答

1

你需要使用winapi,SetConsoleCursorPosition会帮助你。下面是从当前位置移动光标上移一行的最小例如:

#include <iostream> 
#include <windows.h> 

int main() { 
    std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
     "aaaaaaaaaaaaaaa"; 
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 

    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
    GetConsoleScreenBufferInfo(hStdout, &csbiInfo); 
    csbiInfo.dwCursorPosition.Y -= 1; // Move Y coordinate up by one 
    SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition); 

    std::cin.get(); 
} 

另外,Console Functions具有所有必要的功能的整个列表来控制控制台。你会想在你的程序中使用这些。

您需要制作自己的屏幕缓冲区CreateConsoleScreenBuffer,然后将其设置为缓冲区。然后在那之后处理从控制台自己写入和读取的所有内容。

+0

这看起来是我唯一的选择。 –

+0

@CoreyOgburn:在windows上,它可能是最好的选择。像系统这样的Unix可以使终端更容易工作。另一种方法是使用[ncurses for windows](http://gnuwin32.sourceforge.net/packages/ncurses.htm),并具有[wmove函数](http://hughm.cs.ukzn.ac.za/~ murrellh/OS /笔记/ ncurses.html#光标)。 –