【问题标题】:Read only one char from cin仅从 cin 中读取一个字符
【发布时间】:2014-02-25 23:03:09
【问题描述】:

std::cin 读取时,即使我只想读取一个字符。它将等待用户插入任意数量的字符并点击Enter 继续!

我想在用户在终端输入时逐个字符地读取字符并为每个字符执行一些指令。

示例

如果我运行这个程序并输入abcd 然后Enter 结果将是

abcd
abcd

但我希望它是:

aabbccdd

代码如下:

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

请问该怎么做?

【问题讨论】:

  • 我不认为有独立于平台的方式来做到这一点。见:stackoverflow.com/questions/1798511/…
  • @PawełStawarz : string 也不起作用,与char 相同的问题
  • @SeanCline :谢谢,所描述的方法对我有用:)

标签: c++ char cin


【解决方案1】:

以 C++ 友好的方式从流中读取单个字符的最佳方法是获取底层的 streambuf 并在其上使用 sgetc()/sbumpc() 方法。但是,如果 cin 由终端提供(典型情况),则终端可能启用了行缓冲,因此首先需要设置终端设置以禁用行缓冲。下面的示例还禁用了输入字符时的回显。

#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;
}

【讨论】:

  • 我的意思是,什么终端没有行缓冲?
【解决方案2】:

C++ cin 模型是用户在终端中组成一整行,必要时退格和更正,然后当他高兴时,将整行提交给程序。

你不能轻易打破它,你也不应该,除非你想接管整个终端,例如,让一个小人在按键控制的迷宫中游荡。为此,在 Unix 系统上使用 curses.h 或在 DOS 系统上使用 conio.h。

【讨论】:

  • +1 给小个子 :) (因为这都是正确的)。但是对于那个“DOS系统”,我真的也应该对它进行-1,因为答案日期显然是2017年,而不是1997年。;-p
【解决方案3】:

看看:

std::cin.get(char)

【讨论】:

    【解决方案4】:
    #include <iostream>
    #include <conio.h>
    using namespace std;
    
    int main()
    {
        char a;
        do{
            a=getche();
            cout<<a;
        }while(a!='\n');
        return 0;
    }
    

    【讨论】:

    • getche 到底是什么?
    • conio 头文件不标准
    猜你喜欢
    • 1970-01-01
    • 2016-04-06
    • 2011-12-02
    • 2013-08-23
    • 2010-09-14
    • 1970-01-01
    • 2012-04-08
    • 2013-06-27
    相关资源
    最近更新 更多