当参数是目录时,ifstream open()不设置错误位

时间:2012-03-06 20:07:38

标签: c++ ifstream

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

这是一个最小的例子:

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;
}

此处没有错误迹象。如果我继续尝试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”,这是合理的。使用&gt;&gt;运算符抛出一个下溢异常,这也没关系。

现在,我的问题是,我怎么能检测到用户输入了目录名而不是正确的文件名?有没有办法做到这一点?从流中获取和取消输入字节似乎很乏味且容易出错。

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

1 个答案:

答案 0 :(得分:3)

你没有说你的系统是什么,所以很难说,但一般来说, filebuf::open只会在系统级别打开时返回错误 失败。我已经在Unix系统上工作,你可以open() a 目录;我甚至曾经在一些你可以阅读它的地方工作过 打开(至少如果它是本地安装的文件系统)。

至于该怎么做:我能想到的只是尝试get 第一个角色,然后把它放回去。但如果文件是这样,则会失败 空的,所以它也不是真正的解决方案。在系统级别(和 从QoI的角度来看,我希望filebuf::open能够做到这一点 系统确实允许打开目录),您可以使用系统级调用 (Unix中的stat)确定文件是否是目录。 (当然有一种竞争条件:在你发现这种情况之间 这是一个普通的文件,当你做开放的那一刻,另一个过程 可以删除文件并创建目录。它可能不是一个 然而,频繁出现。)