为什么,当我使用以下代码段时,无论文件大小如何,结果都为零,但当我在ios::binary
中删除open()
时,它会执行它应该执行的操作?
fstream f1;
streampos begin, end;
f1.open("file1", ios::binary);
f1.seekg(0, ios::beg);
begin = f1.tellg();
f1.seekg(0, ios::end);
end = f1.tellg();
f1.close();
cout << end - begin << endl;
答案 0 :(得分:8)
我假设通过&#34;当我删除ios::binary
&#34;你的意思是删除整个论点:
f1.open("file1");
函数open()
有两个参数 - 文件名和模式。模式1的默认参数为std::ios_base::in | std::ios_base::out
。因此,如果您没有指定任何内容,则会使用此deault。
但是,如果指定ios::binary
,则替换默认参数。由于您既未指定in
也未指定out
,因此open()
调用失败。在if()
附近设置open()
会告诉您 - 记住您应该始终通过I / O检查错误。
答案 1 :(得分:1)
std::ios_base::binary
本身不是std::basic_fstream
的有效开放模式。有效的开放模式组合可以在表132中找到:
std::basic_fstream
及其open()
方法的构造函数都将open()
方法转发到内部std::basic_filebuf
到rdbuf()->open(s, mode)
,其中mode
是mode
用于openmode。从表中可以看出,ios_base::binary
(模式为modstr
)本身并不是有效标志。当文件缓冲区确定此时,打开失败:
NTBS
mode & ~ios_base::ate
由mode
确定,如表132所示。如果mode
不是表格中显示的某些标志组合,则打开失败。
打开文件时,out | in
与std::basic_filebuf::open()
按位或“不”的原因是因为它不清楚您是否要使用该流进行输入或输出(它假定你知道你想要什么)。由于模式不是有效标志组合,setstate(std::ios_base::failbit)
返回空指针。这是由流选取的,而流又调用rdbuf()->open(s, mode)
。
[..]调用
setstate(failbit)
。如果该函数返回空指针,则调用tell
。
当流处于失败状态时,其-1
方法返回0
。这就是你在减去std::fstream f1("file1", std::ios_base::in | std::ios_base::ate | std::ios_base::binary);
std::cout << f1.tellg();
时获得{{1}}的原因。
如果你想要的只是大小,这是打开它的正确方法:
{{1}}
答案 2 :(得分:0)
如果您的尺寸为0,请检查文件是否已打开...
#include<iostream>
#include<fstream>
using namespace std;
int main(){
fstream f1;
streampos begin, end;
f1.open("Data.txt", ios::binary);
if (f1.is_open()) {
cout << "Open" << endl;
}
f1.seekg(0, ios::beg);
begin = f1.tellg();
f1.seekg(0, ios::end);
end = f1.tellg();
f1.close();
cout << end - begin << endl;
system("pause");
}
如果没有打开,您可能已尝试打开文本文件。
在文本文件中,ios :: binary标志不包含在打开模式中。文本文件用于存储文本数据,当对它们进行二进制输入/输出操作时,这可能导致格式转换。