【问题标题】:ios_base::sync_with_stdio(false) does not work between two inputs from stdinios_base::sync_with_stdio(false) 在标准输入的两个输入之间不起作用
【发布时间】:2016-05-26 18:35:19
【问题描述】:

我想知道为什么下面的代码不能按预期工作:

#include <iostream>
#include <string>
using namespace std;

int main(){
    int n;
    string s;
    //scanf("%d",&n);
    cin >> n;
    ios_base::sync_with_stdio(false);
    cin >> s;
    cout << n << " " << s;
    return 0;
}

输入:

10 
abcd 

输出:10

字符串没有被打印出来!如果我使用scanf 输入整数,结果是一样的。但是,如果将ios_base::sync_with_stdio(false); 行放在第一个cin 之前(或scanf 之前),则代码确实可以正常工作。

对于澄清这种行为的任何帮助,我将不胜感激。

编辑: 输入包含在文件inp.txt 中,我使用&lt;(重定向运算符)从文件中读取,&gt; 将结果输出到out.txt,例如: a.out &lt; inp.txt &gt; out.txt

如果输入是直接从控制台给出的,那么代码会给出预期的输出。如有任何误解或困惑,请见谅。

【问题讨论】:

  • 这个documentation 声明sync_with_stdio() 必须是对io 系统的第一次调用。 - “如果在标准流上发生某些 I/O 后调用此函数是否有任何效果,则由实现定义。”
  • 添加
  • @Mr.分支:我应该在哪里添加&lt;&lt; endl?另外,如果stdout 被刷新会有什么帮助? (我认为这里的问题在于stdin,而不是stdout。)。
  • 我在我的电脑上运行了程序并且没有问题 cin>>n 占据了整行你尝试 10(enter) 然后是字符串吗?也是 之后的
  • @Mr.Branch:程序在你的电脑上完美运行!那很奇怪!所以,这确实取决于实现细节。顺便说一句,输入是用空格还是换行符分隔在我的机器上没有任何区别。 &lt;&lt; endl&lt;&lt; s 之后也不好。

标签: c++ iostream cin stdio


【解决方案1】:

在执行 I/O 之后调用sync_with_stdio会导致实现定义的行为(这比 cppreference 的“有任何影响”的措辞更强):

效果:如果在调用之前使用标准流发生了任何输入或输出操作,效果是 实现定义。否则,用错误的参数调用,它 允许标准流独立于标准 C 运行 流。

在 libc++ 中,什么都不会发生,因为它所做的只是切换一个标志。在 libstdc++ 中,它实际上执行logic 来切换流。任何进一步尝试使用流都会导致失败:

cin >> s;
cin.clear();
cin >> s;
std::cout << n << " " << s;

无论哪种方式,the libstdc++ manual 声明您需要在执行 I/O 之前调用函数。所以你现在实际上拥有的是未定义的行为。

【讨论】:

  • 我的代码在结合使用&lt; 运算符读取文件时没有给出预期的输出,对于直接在控制台中给出的输入,它工作正常。
  • @SnehasishKarmakar 当您使用控制台时,没有缓冲区可以丢失您的输入字符串
猜你喜欢
相关资源
最近更新 更多
热门标签