ios_base::ate and tellp()

3
#include <fstream>
#include <iostream> 

int main() 
{ 
    const char* fileName = "out1"; 
    std::ofstream fs1(fileName); 
    fs1 << "AAAAAAAAAAA\n"; 
    std::cout << fs1.tellp() << std::endl; 
    fs1.close(); 

    std::ofstream fs2(fileName, std::ios_base::ate); 
    std::cout << fs2.tellp() << std::endl; 
    fs2.close(); 

    return 0;   
}   

gcc版本为4.4.6 20120305(Red Hat 4.4.6-4)(GCC)

g++ file02.cpp

./a.out

12 0

为什么fs2.tellp()输出0而不是12?

2个回答

4
当您使用std::ofstream打开文件进行输出时,如果未设置std::ios_base ::instd::ios_base ::out或者未在模式参数中设置std::ios_base::app,文件将被截断。
传递给std::ofstreamstd::ifstream构造函数的模式参数将转发到std::filebuf::open成员函数。它的值根据映射到C库函数fopen的模式参数对应行为来确定文件的打开方式。该映射会考虑除std::ios_base::ate以外的所有标志。总之,映射如下:
Flag combination:  in  out trunc app | fopen mode
                        +              "w"
                        +         +    "a"
                                  +    "a"
                        +    +         "w"
                   +                   "r"
                   +    +              "r+"
                   +    +    +         "w+"
                   +    +         +    "a+"
                   +              +    "a+"
(C++03省略了设置app但未设置out的行;这些现在等同于设置了appout的行。)
另外,如果设置了std::ios_base::binary,则将“b”添加到fopen模式的结尾。
如果传递的标志组合(忽略std::ios_base::ate)与这些组合不匹配,则打开操作应该失败。
请注意,对于模式"w""w+"fopen会截断文件。 std::ios_base::ate将在打开文件时将位置设置为文件末尾。只有当模式参数的其余部分不会导致打开的文件被截断且文件已经存在且具有非零大小时,这才会产生影响。

std::ios_base::ate是什么意思? - Alex
@Alex:这有什么关系吗?它不会影响输出文件是否被截断;它只是在打开时将光标定位到文件末尾。显然,它只有在文件未被截断的情况下才会产生影响。 - CB Bailey
在打开流时,将流的位置指示器设置为流的末尾。没有关于截断的内容。 - Alex
@Alex:是的,它不会影响截断行为。请注意,如果您只提供ate而不是out,则应该失败,因为您没有指定与标准中的fopen模式字符串对应的模式标志的有效组合;您需要(至少)out | ate,但您可能想要像"r+"这样的东西,它是in | out,您还可以选择添加ate。只有out | ate将被截断,因为它等同于"w" - CB Bailey

0
你在再次以写入模式打开文件时没有提供 out 标志。请按照以下方式执行:
std::ofstream fs2(fileName, std::ios_base::out | std::ios_base::ate);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接