Ifstream open()在参数是目录时不设置错误位 [英] Ifstream open() doesn't set error bits when argument is a directory

查看:168
本文介绍了Ifstream open()在参数是目录时不设置错误位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++程序中,使用std :: ifstream,我试图打开一个用户指定的文件 - 到目前为止这么好。但是,我不小心输入了一个实际上是一个目录的文件名,我很惊讶地看到试图打开()该目录没有生成任何错误。



这里一个最小示例:

  std :: ifstream f; 
f.open(..);
if(!f.is_open()||!f.good()|| f.bad()|| f.fail()){
std :: cout< 打开时设置错误位< std :: endl;
return 1;
}

这里没有错误的迹象。如果我继续尝试getline(),getline()设置一个错误位。

  std :: string str ; 
getline(f,str);

if(f.eof())std :: cout< getline set eofbit< std :: endl;
else if(f.bad())std :: cout<< getline set badbit< std :: endl;
else if(f.fail())std :: cout<< getline set failbit< std :: endl;

这将输出getline set badbit,这是合理的。使用>>运算符引发一个下溢异常,这也是可以的。



现在,我的问题是,如何检测用户输入的目录名称,而不是正确的文件名?有什么办法吗?从流中获取和取消读取字节似乎乏味且容易出错。



此外,为什么会这样?我意识到,从程序的角度看,这都是相同的数据,但我认为操作系统也会发送一些嘿,这是一个目录的消息。


<你不会说你的系统是什么,所以很难说,但一般来说,
filebuf :: open

/ code>将只会返回一个错误,如果你的系统级别打开
失败。我在Unix系统上工作,你可以 open() a
目录;我甚至曾经在一些地方你可以在
打开后阅读它(至少如果它是一个本地安装的文件系统)。



至于怎么办:我可以想到的是尝试 get
第一个字符,然后将其放回。但是如果文件是
为空,这将失败,因此它也不是一个解决方案。在系统级别(和
从QoI的角度来看,如果
系统允许的话,我希望 filebuf :: open 打开目录),可以使用系统级调用
(Unix中的 stat )来确定文件是否是目录。
(当然有一个竞争条件,当你检测到
是一个正常的文件,并且你打开的时候,另一个进程
可以删除该文件并创建一个目录。然而,它可能不是一个
频繁出现。)


In a C++ program, using std::ifstream, I'm attempting to open a user-specified file -- so far so good. However, I accidentally entered a filename that's actually a directory, and I was quite surprised to see that attempting to open() that directory didn't generate any errors.

Here's a minimal example:

std::ifstream f;
f.open("..");
if(!f.is_open() || !f.good() || f.bad() || f.fail()) {
    std::cout << "error bit set on open" << std::endl;
    return 1;
}

No sign of error here. If I go on and attempt to getline(), getline() sets an error bit all right.

std::string str;
getline(f, str);

if(f.eof()) std::cout << "getline set eofbit" << std::endl;
else if(f.bad()) std::cout << "getline set badbit" << std::endl;
else if(f.fail()) std::cout << "getline set failbit" << std::endl;

This outputs "getline set badbit", which is reasonable. Using the >> operator throws an underflow exception, which is also okay.

Now, my question is, how could I detect that the user entered a directory name instead of a proper filename? Is there any way to do that? Getting and ungetting bytes from the stream seem tedious and error-prone.

Also, why is this so? I realize that it's all just the same data from the point of view of the program, but I'd assume the OS would also send some "hey, this is a directory" kind of message.

解决方案

You don't say what your system is, so it's hard to say, but generally, filebuf::open will only return an error if your system level open fails. And I've worked on Unix systems where you could open() a directory; I've even worked on some where you could read it after the open (at least if it was a locally mounted filesystem).

As to what to do about it: about all I can think of is to try to get the first character, then put it back. But this fails if the file is empty, so it's not really a solution either. At the system level (and from a QoI point of view, I'd expect filebuf::open to do this if the system did allow opening a directory), you can use a system level call (stat in Unix) to determine whether the file is a directory or not. (There's a race condition, of course: between the moment you detect that it's a normal file, and the moment you do the open, another process could delete the file and create a directory. It's probably not a frequent occurance, however.)

这篇关于Ifstream open()在参数是目录时不设置错误位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆