std::cin >> c;将数字读入数组后被忽略

std::cin >> c; gets ignored after reading numbers into array

我正在尝试将一些数字输入到数组中。 很简单的任务。

int array[100], n = 0, length = 0;
std::cout << "Input numbers: " << std::endl;
while (std::cin >> n) {
    array[length++] = n;
}

我在 CLion 中按 shift + F10,试图 运行 它和

它不会结束(我连续按了 5 次回车),它会一直持续下去。 我是不是做错了什么?

我尝试在每次输入后使用 std::cin.ignore()。好像没什么效果。

谢谢!

编辑:当我按 ctrl-D 时它确实成功结束,但我遇到了另一个问题。 (我编辑了标题)

我有这个程序:

void read_input(int arr[], int &length) {
    int n = 0;
    std::cout << "Read input: " << std::endl;
    while (std::cin >> n) {
        arr[length++] = n;
    }
}

int main() {
    int array[100], length = 0;
    int c = -1;

    while (true) {
        std::cout << "Menu: (TO DO)\n";
        std::cout << "Your option: ";
        std::cin >> c;

        if (c == 1) {
            read_input(array, length);
        }
        if (c == 0) break;
    }
}

结果是,我输入选项:

1
Read input:
1
2
3
4
^D

Menu: (TO DO)
Your option:
Read input:
Menu: (TO DO)
Your option:
Read input:
Menu: (TO DO)
Your option:
Read input:
...

基本上,在它进入 read_input() 并且我给它一些数字后,我按 ctrl-D 它不会再问我要 input/option,它会只需一遍又一遍地阅读 1 for std::cin >> c;,它将永远持续下去。

你应该使用 for 循环:

for(int i=0; i<5; i++)
{
  std::cin>>n;
  array[i]=n;
}

或者如果你想在换行符上完成输入:

std::string input="";
while(input!="\n")
{
  getline(std::cin,input);
  n=std::stoi(input);
  array[length++]=n;
}

输入序列开头的空格不会被丢弃。您可以使用 std::ws 函数丢弃空格,该函数是一种操纵器,旨在从输入流的开头提取和丢弃前导空格。

您可以使用 from getline() 来完成它。

#include <iostream>
#include <string>

void read_input(int arr[], int& length) {
    int n = 0;
    std::cout << "Read input: " << std::endl;
    std::string num_str{};
    while (std::getline(std::cin >> std::ws, num_str)) {
        try
        {
            n = std::stoi(num_str);
            arr[length++] = n;
        }
        catch(...)
        {
            break;
        }
    }
}

int main() {
    int array[100], length = 0;
    int c = -1;
    
    while (true) {
        std::cout << "Menu: (TO DO)\n";
        std::cout << "Your option: ";

        std::string str;
        std::getline(std::cin >> std::ws, str);
        try
        {
            c = std::stoi(str);
        }
        catch(...)
        {
            c = -1;
        }
        
        if (c == 1) {
            read_input(array, length);
        }
        if (c == 0) break;
    }
}

您很可能只需要在 read_input 循环结束时清除流并确保忽略输入缓冲区中剩余的任何内容:

void read_input(int arr[], int &length) {
  int n = 0;
  std::cout << "Read input: " << std::endl;
  while (std::cin >> n) {
    arr[length++] = n;
  }
  std::cin.clear();
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

虽然 Ctrl-D 来标记序列的结束似乎是一个不寻常的选择,但为什么不使用专用字符来标记输入的结束并安全地丢弃它。

Ctrl+D 之前读取用户输入的方法不是一个好主意,因为它会给您的程序带来很多问题,并且在其他平台上 运行 时可能会出现潜在错误。 Ctrl+D 关闭系统级管道,所以我不确定在被 EOF 停止后是否有正确的方法来恢复输入流。正如我所说,即使您找到了适用于您的环境的解决方案,但仍有可能出现潜在错误。因此,我的建议是使用一个哨兵(这里,eof 作为字符串)来替换 Ctrl+D.

#include <iostream>
#include <string>


void read_input(int arr[], int &length) {
    std::cout << "Read input (enter `eof` when you are done): " << std::endl;

    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    std::string number; 
    while (std::getline(std::cin, number) && number != "eof")
    {
        arr[length++] = std::stoi(number);
    }
}

int main() {
    int array[100], length = 0;
    int c = -1;

    while (true) {
        std::cout << "Menu: (TO DO)\n";
        std::cout << "Your option: ";
        std::cin >> c;

        if (c == 1) {
            read_input(array, length);
        }
        if (c == 0) break;
    }
}

输出:

Menu: (TO DO)
Your option: 1
Read input (enter `eof` when you are done): 
1
2
3
eof
Menu: (TO DO)
Your option: 1
Read input (enter `eof` when you are done): 
1
2
3
4
5
eof
Menu: (TO DO)
Your option: 2
Menu: (TO DO)
Your option: 0
Process exited with status 0

您可以将 eof 替换为您喜欢的任何内容,但此任务的数字除外。

你的问题好像是n的值;输入 \n 时是 0 吗?

我喜欢 here 给出的解决方案:用 getline() 捕获 cin,其中 returns 是一个字符串。然后你可以检查 isempty() 是否有任何输入。您需要使用 stof()stol() 转换为数字,但这应该是可行的。