是ios :: app模式和fstream :: write以某种方式彼此不兼容吗?

时间:2015-01-15 05:31:40

标签: c++ fstream

当使用fstream::write模式打开文件时ios::app失败,当使用ios::out模式打开文件时没有此类问题时,我感到非常困惑。

ios::app模式与fstream::write之间是否存在某种程度的不相容?

示例代码:

#include <iostream>
#include <fstream>

void test1()
{
   char const* fname = "out-1.txt";
   std::fstream out;
   out.open(fname, std::ios::app | std::ios::binary);
   if(!out)
   {
      std::cerr << "Cant open file " << fname << " to write to.\n";
      return;
   }

   int val = 10;
   out.write(reinterpret_cast<char*>(&val), sizeof(val));
   if (!out )
   {
      std::cerr << "Error in writing " << val << " to file with ios::app mode.\n";
   }
}

void test2()
{
   char const* fname = "out-2.txt";
   std::fstream out;
   out.open(fname, std::ios::out | std::ios::binary);
   if(!out)
   {
      std::cerr << "Cant open file " << fname << " to write to.\n";
      return;
   }

   int val = 10;
   out.write(reinterpret_cast<char*>(&val), sizeof(val));
   if (!out )
   {
      std::cerr << "Error in writing " << val << " to file with ios::out mode.\n";
   }
}

int main()
{
   test1();
   test2();
   return 0;
}

使用g ++ 4.8.2运行程序的输出:

Error in writing 10 to file with ios::app mode.

2 个答案:

答案 0 :(得分:3)

我尝试了你的代码,它在4.9.2上运行良好,标签的快速差异显示如下:

diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 483a576..21a67cd 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -1,6 +1,6 @@
 // File based streams -*- C++ -*-

-// Copyright (C) 1997-2013 Free Software Foundation, Inc.
+// Copyright (C) 1997-2014 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -423,7 +423,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       int_type __ret = traits_type::eof();
       const bool __testeof = traits_type::eq_int_type(__c, __ret);
-      const bool __testout = _M_mode & ios_base::out;
+      const bool __testout = (_M_mode & ios_base::out
+                             || _M_mode & ios_base::app);
       if (__testout)
        {
           if (_M_reading)
@@ -640,7 +641,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Optimization in the always_noconv() case, to be generalized in the
       // future: when __n is sufficiently large we write directly instead of
       // using the buffer.
-      const bool __testout = _M_mode & ios_base::out;
+      const bool __testout = (_M_mode & ios_base::out
+                             || _M_mode & ios_base::app);
       if (__check_facet(_M_codecvt).always_noconv()
           && __testout && !_M_reading)
        {

tl;它是一个错误,它已在gcc 4.9中修复


来自提交:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59427

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3945.html#596

虽然标准中没有明确提及(据我所知),链接的缺陷提到app可能意味着out

答案 1 :(得分:0)

感谢@ user657267的评论,我试过了:

out.open(fname, std::ios::out | std::ios::app | std::ios::binary);

它有效。奇怪。我一直认为std::ios::out | std::ios::app等于std::ios::appthis accepted answer to another SO question

表明了这一点