> 可能是错的?),c++,debugging,visual-c++"/>

首页 > 解决方案 > 这是 C++ 中的错误吗?(书<> 可能是错的?)

问题描述

//Wrong Code
#include<iostream>
#include<iterator>
using namespace std;
int main(){
    istream_iterator<string> in_iter(cin),eof;
    ostream_iterator<string> out_iter(cout," ");
    while(in_iter!=eof)
        *out_iter++ = *in_iter++;
}

输入:(通过“visual c++”、“cpp.sh”、“onlinegdb”和任何你喜欢的工具以交互模式运行上面的代码……)

aa bb cc 6 dd ee

输出:

aa bb cc 6 dd

实际上正确的代码应该是:

#include<iostream>
#include<iterator>
using namespace std;
int main(){
    istream_iterator<string> in_iter(cin),eof;
    ostream_iterator<string> out_iter(cout," ");
    while(in_iter!=eof){
        *out_iter = *in_iter;
         out_iter++;
         in_iter++;
    }
}

输入:

aa bb cc 6 dd ee

输出:

aa bb cc 6 dd ee

描述:非常简单的代码。仅用于打印一些字符和输出将是相同的。然而,在《C++ Primer》一书中,如下图所示,它给了我们一个错误的代码。是 C++ 的错误还是“C++ Primer”的错误? 《C++入门》图片

标签: c++debuggingvisual-c++

解决方案


让我们拆开这个命令,看看发生了什么:

*out_iter++ = *in_iter++;

根据运算符的优先级,也可以写成如下方式:

// read next value, but return unmodified iterator (with the previous value)
// the first value is read when the iterator is constructed!
auto x = in_iter++; 

// get value that was previously read
const auto res = *x; 

// print this value
*out_iter++ = res;

所以基本上这只会在阅读下一个值后打印一个值。对于"a b c"以下情况的输入:

  1. 构造函数istream_iterator<string> in_iter(cin)读取"a"
  2. auto x = in_iter++;读取"b",但返回一个包含"a"
  3. const auto res = *x;结果"a",然后打印。
  4. auto x = in_iter++;读取"c",但返回一个包含"b"
  5. const auto res = *x;结果"b",然后打印。
  6. auto x = in_iter++;尝试读取某些内容,但流缓冲区为空,因此它等待进一步的输入。

到目前为止,仅"a b"被打印并"c"“卡在” in_iter.

如果流包含一个[eof](例如,如果您以某种方式终止流),则第 6 步将有所不同,第 7 步(和第 8 步)将发生:

  1. auto x = in_iter++;读取[eof],成为 eof-iterator 并返回一个包含"c"
  2. const auto res = *x;结果"c",然后打印。
  3. 循环终止

所以这段代码没有错,它只是没有做人们直觉所期望的事情。


另一方面,您的代码执行以下操作:

// extract first value that was read by the constructor and "prepare" to print
*out_iter = *in_iter; 

// read next value
out_iter++;

// print value
in_iter++;

这可以按预期工作,因为它确实会在读取新值之前打印旧值。


推荐阅读