ios_base :: ate和tellp()

时间:2013-01-23 13:25:49

标签: c++

#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 version 4.4.6 20120305(Red Hat 4.4.6-4)(GCC)

g ++ file02.cpp

./ a.out

12 0

为什么fs2.tellp()打印0,但不打印12?

2 个答案:

答案 0 :(得分:3)

当您使用std::ofstream打开文件以进行输出时,除非您同时设置std::ios_base::instd::ios_base::out,或者在模式参数中设置std::ios_base::app,否则会将其截断。 / p>

传递给std::ofstreamstd::ifstream的构造函数的mode参数将转发到std::filebuf::open成员函数。其值根据映射到C库函数fopen的mode参数的相应行为来确定文件的打开方式。此映射考虑除std::ios_base::ate之外的所有标志集。总之,映射如下:

Flag combination:  in  out trunc app | fopen mode
                        +              "w"
                        +         +    "a"
                                  +    "a"
                        +    +         "w"
                   +                   "r"
                   +    +              "r+"
                   +    +    +         "w+"
                   +    +         +    "a+"
                   +              +    "a+"

(C ++ 03省略了设置appout未设置的行;这些行现在等同于设置了appout的行。)< / p>

此外,如果设置了std::ios_base::binary,则b会附加到fopen模式等效项。

如果传递的标志组合(忽略std::ios_base::ate)与这些组合中的一个不匹配,那么打开的应该失败。

请注意,fopen会截断模式"w""w+"的文件。

std::ios_base::ate会在打开文件时将位置设置为文件末尾。仅当模式参数的其余部分不会导致打开的文件被截断并且文件已存在且大小非为零时,这将起作用。

答案 1 :(得分:0)

再次打开文件进行写入时,您没有提供out标志。这样做:

std::ofstream fs2(fileName, std::ios_base::out | std::ios_base::ate);