ios::app 模式和 fstream::write 是否互不兼容?
Are ios::app mode and fstream::write somehow incompatible with each other?
我很纳闷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 的程序的输出:
使用 ios::app 模式将 10 写入文件时出错。
感谢@user657267 的评论,我尝试了:
out.open(fname, std::ios::out | std::ios::app | std::ios::binary);
它奏效了。奇怪的。我一直认为 std::ios::out | std::ios::app
等于 std::ios::app
。 this accepted answer to another SO question.
中显示了这么多
我试过你的代码,它在 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;dr 这是一个错误,已在 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
.
我很纳闷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 的程序的输出:
使用 ios::app 模式将 10 写入文件时出错。
感谢@user657267 的评论,我尝试了:
out.open(fname, std::ios::out | std::ios::app | std::ios::binary);
它奏效了。奇怪的。我一直认为 std::ios::out | std::ios::app
等于 std::ios::app
。 this accepted answer to another SO question.
我试过你的代码,它在 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;dr 这是一个错误,已在 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
.