代码之家  ›  专栏  ›  技术社区  ›  AnR

ofstream:运行索引不起作用[重复]

  •  1
  • AnR  · 技术社区  · 8 年前

    我想在一个文件中写几行。每行都有一个索引(运行索引)。 我的代码是:

    ofstream outputFile;
    int index = 0;
    
    outputFile << ++index << ") FirstLine" <<endl
               << ++index << ") SecondLine" <<endl
               ...
               << ++index << ") LastLine" <<endl;
    

    问题是我没有得到运行索引。也就是说,所有行都有相同的索引(即总行数)。所以,我的问题首先是,流是如何工作的(即为什么我会得到所描述的结果)。其次,我应该怎么做才能让它工作?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Binary Birch Tree    8 年前

    首先,of流是如何工作的(即为什么我会得到所描述的结果)?

    根据C++标准(第1.9节第15条):

    除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值都是无序的。

    如果标量对象上的副作用相对于同一标量对象的另一副作用或使用同一标数对象的值进行的值计算是未排序的,并且它们不可能并发,则行为是未定义的。

    适用于您的案例:

    • 评估 ++index 语句(是 << 运算符)未排序。

    • ++索引 修改的值 index ,因此对标量对象有副作用。

    • 因此,行为是未定义的。

    其次,我应该怎么做才能让它工作?

    一个简单的选项是将单个大型输出表达式拆分为多行,以便 ++索引 语句位于单独的一行。

    或者,您可以同时解决问题和 reduce repetition 通过使用循环。

    例如:

    #include <array>
    #include <iostream>
    #include <string>
    
    int main () {
      static const std::array<std::string, 3> lines = {
        "First line",
        "Second line",
        "Last line",
      };
    
      for (int i = 0; i < lines.size(); ++i) {
        std::cout << i + 1 << ") " << lines[i] << std::endl;
      }
    }
    

    将此另存为 example.cc ,并使用以下命令进行编译:

    clang++ -std=c++14 example.cc -o example
    

    然后运行示例:

    $ ./example
    1) First line
    2) Second line
    3) Last line
    

    注意,这会打印到标准输出以简化示例,但是 std::cout 可以很容易地替换为 std::ofstream 取决于您的用例。