【问题标题】:Read from stdin in C++从 C++ 中的标准输入读取
【发布时间】:2014-04-06 18:33:12
【问题描述】:

这是我的代码:

...
...
do
{
    cin >> command;

    switch(command)
    {
        case 'i':
            cin >> key >> nome >> idade >> endereco;
            count++;

            pessoas = (Pessoa **) realloc(pessoas, count*sizeof(Pessoa *));
            pessoas[count-1] = new Pessoa(key, nome, idade, endereco);

            bTree->add(pessoas[count-1]);
            break;

        case 's':
            cin >> key;

            toSearch = (Pessoa *) bTree->search(key);

            if(toSearch == NULL)
            {
                cout << "-1" << endl;
            }
            else
            {
                cout << key << endl;
                cout << toSearch->getNome() << endl;
                cout << toSearch->getIdade() << endl;
                cout << toSearch->getEndereco() << endl;
            }

            break;

        case 'e':
            done = true;
            break;
    }

} while(!done);
...
...

我有一个“菜单”,当我输入i 时,它将插入BTree,s 将搜索,e 将退出程序。

问题是,当我点击i插入时,我必须给四个参数:

  1. (int) 密钥;
  2. (字符串)名称;
  3. (int) 年龄;
  4. (字符串)地址;

当我给出一个包含e 字符的名称(例如“James”)时,它将退出程序。

如何避免command 在切换时读取标准输入缓冲区?

示例输入:

i
1
Joao da Silva 1
11
Rua 2, 3
i
2
Joao da Silva 2
12
Rua 4, 6
s
1
s
7
e

谢谢。

【问题讨论】:

  • 有什么理由不使用std::vector 代替pessoas
  • 这跟我的问题有关系吗?如果我只需要一个 realloc,为什么还要浪费堆栈?
  • 还没有发现任何错误,只是想知道你为什么不在那里写惯用的 C++。
  • commandchar 吗?
  • “这跟我的问题有关系吗?如果我只需要一个 realloc,为什么还要浪费堆栈?” ---(1)这与问题无关,(2)关于“浪费堆栈”的说法毫无意义。始终使用std::vector

标签: c++ stdin


【解决方案1】:

std::basic_istream::get(定义 1)怎么样?

这将使您的 switch 语句开始如下。

do
{    
    switch(cin.get())
    {

请记住,在一般情况下,在您的switch 中尽早检查std::char_traits::eof 可能是谨慎的(尽管对于标准输入来说这不是必需的)。

【讨论】:

  • 这很可能是 EOF 的情况。在 shell 中使用 &lt; 相当于将标准输入绑定到文件,因此 EOF 是一个问题。
  • 可能是因为我在cin 上使用了空格?
  • 也可以。您能否将输入文件的描述添加到原始帖子中?
  • 我认为这需要分成一个不同的问题。 cin.get() 解决了您最初的问题。您遇到的其余问题与换行符是字符和空格相关,导致字符串与 cin 中断。我建议查看 getline。
  • 对不起,不能接受...它没有解决我的问题..当我点击不是ies的东西时,它会进入一个无限循环。
【解决方案2】:

使用fgetc完成:

...
...
while(!done)
{
    cin >> command;

    switch(command)
    {
        case 'i':
            scanf("%d\n", &key);

            strCounter = 1;
            while(true)
            {
                buff = fgetc(stdin);

                // until the user types '\n'
                if(buff == '\n')
                {
                    nome[strCounter-1] = '\0';
                    break;
                }

                // realloc it
                nome = (char *) realloc(nome, (strCounter)*sizeof(char));
                nome[strCounter-1] = buff;
                strCounter++;
            }

            scanf("%d\n", &idade);

            strCounter = 1;
            while(true)
            {
                buff = fgetc(stdin);

                // until the user types '\n'
                if(buff == '\n')
                {
                    endereco[strCounter-1] = '\0';
                    break;
                }

                // realloc it
                endereco = (char *) realloc(endereco, (strCounter+1)*sizeof(char));
                endereco[strCounter-1] = buff;
                strCounter++;
            }

            count++;

            pessoas = (Pessoa **) realloc(pessoas, count*sizeof(Pessoa *));
            pessoas[count-1] = new Pessoa(key, nome, idade, endereco);

            bTree->add(pessoas[count-1]);

            break;

        case 's':
            cin >> key;

            toSearch = (Pessoa *) bTree->search(key);

            if(toSearch == NULL)
            {
                cout << "-1" << endl;
            }
            else
            {
                cout << key << endl;
                cout << toSearch->getNome() << endl;
                cout << toSearch->getIdade() << endl;
                cout << toSearch->getEndereco() << endl;
            }

            break;

        case 'e':
            done = true;
            break;

        default:
            break;
    }
}
...
...

【讨论】: