第二个 cin 被跳过或无法正常工作

Posted

技术标签:

【中文标题】第二个 cin 被跳过或无法正常工作【英文标题】:Second cin is either skipped or does not work properly 【发布时间】:2017-01-30 13:08:10 【问题描述】:

我有几个问题,我认为这些问题密切相关,但我无法按照我之前在网站上找到的内容解决这些问题。

我的问题与在我的 main 函数中双重使用 cin 有关。我需要从键盘读取数字以构建小向量或存储单个系数。我无法提前知道要构建的向量的长度。

以下是涉及的行:

#include <vector>
#include <iostream>
#include <limits>

int main() 
    ...
    double a=0;
    std::vector<double> coefficients;
    while (std::cin>>a) 
       coefficients.push_back(a);
    
    ...
    std::vector<double> interval;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max());
    while(std::cin>>a) 
       interval.push_back(a);
    
    std::cout<<interval.size()<<std::endl;
    std::cout<<*interval.cbegin()<<" "<<*(interval.cend()-1)<<std::endl;
    ...

我同时使用带有 g++ 6.3.0 的 macOS 和带有 g++ 5.3.0 的 Linux。我发送给编译器的标志是-Wall -std=c++14 -o。 在 macOS 机器上,第二个 cin 被完全跳过,而在 Linux 上,第二个读取过程的行为不像预期的那样。我的意思是,如果我在第二个cin 处给出-1 1,则打印的向量大小为0,显然,程序由于分段错误而停止。

在每个cin,我在一行中输入请求的数字,例如1 0 0 1,然后按回车键,然后按ctrl+D。

在此先感谢大家! :)

【问题讨论】:

您是否考虑过改用getline 是的,我做到了,除了删除cin.ignore 行之外,还可以让我的代码在 Linux 机器上按预期运行。但是,macOS 并非如此。所以,我应该一劳永逸地放弃cin 【参考方案1】:

您对std::cin.ignore(...) 的调用设置了流的失败位。这使得无法进入循环。您需要在循环之前移动 std::cin.clear() 调用,以使其运行。当第二个容器中没有数据时,您也会出现越界读取。

#include <vector>
#include <iostream>
#include <limits>
#include <string>

int main() 
    double a=0;
    std::vector<double> coefficients;
    while (std::cin>>a) 
       coefficients.push_back(a);
    
    std::cout << coefficients.size() << '\n';

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'X');
    std::cin.clear();
    char c;
    std::cin>>c;
    if(c != 'X')
    
        std::cerr << "Invalid separator\n";
        return 1;
    

    std::vector<double> interval;
    while(std::cin >> a) 
       interval.push_back(a);
    
    std::cout<< interval.size()<<std::endl;
    if(interval.size())
        std::cout<<*interval.cbegin()<<" "<<*(interval.cend()-1)<<std::endl;

    return 0;

用下面的数据文件,

$ cat data.txt
12 23
42
X
1 2
3 4 5

生成此输出:

$ ./a.out < data                  
3
5
1 5

【讨论】:

谢谢!我不知道std::cin.ignore() 设置了流的失败位。现在该程序在 Linux 上运行良好。在 macOS 上仍然没有变化,但现在这是次要的。【参考方案2】:

您需要在cin.ignore() 中添加一个换行符'\n' 作为第二个参数,这样它就可以在回车时消除忽略

【讨论】:

是的,我也尝试过,但没有任何改变。在 macOS 上,第二个 cin 只是被跳过,在 Linux 上它仍然无法正常工作,正如我上面解释的那样。

以上是关于第二个 cin 被跳过或无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

为什么连续的scanf会被跳过或不执行

cin >>type 循环中执行怎么被跳过了??

为啥 Laravel 跳过第二个 Foreach()

Thread.sleep() 不工作。被跳过的操作

第二个和第三个分布式 Kafka 连接器工作人员无法正常工作

如何跳过或忽略标题上方的行?