- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
istreambuf_iterator 什么时候抛出异常?当底层流试图读取一个目录时,我收到一个异常,但在其他情况下没有。具体来说,我从 Jan-Philip Gehrcke 的 blog 中获取了脚本 readfile_tests.sh
并稍作修改:
$ cat readfile_tests.sh
#!/bin/bash
COMPILATION_SOURCE=$1
NE_FILE="na"
EMPTY_FILE="empty_file"
ONE_LINE_FILE="one_line_file"
INVALID_LINE_FILE="invalid_line_file"
FILE_READ="file_read"
FILE_WRITTEN="file_written"
FILE_DENIED="/root/.bashrc"
DIR="dir"
# compile test program, resulting in a.out executable
g++ -std=c++11 $COMPILATION_SOURCE
# create test files / directories and put them in the desired state
touch $EMPTY_FILE
if [[ ! -d $DIR ]]; then
mkdir $DIR
fi
echo "rofl" > $ONE_LINE_FILE
echo -ne "validline\ninvalidline" > $INVALID_LINE_FILE
echo "i am opened to read from" > $FILE_READ
python -c 'import time; f = open("'$FILE_READ'"); time.sleep(4)' &
echo "i am opened to write to" > $FILE_WRITTEN
python -c 'import time; f = open("'$FILE_WRITTEN'", "a"); time.sleep(4)' &
# execute test cases
echo "******** testing on non-existent file.."
./a.out $NE_FILE
echo
echo "******** testing on empty file.."
./a.out $EMPTY_FILE
echo
echo "******** testing on valid file with one line content"
./a.out $ONE_LINE_FILE
echo
echo "******** testing on a file with one valid and one invalid line"
./a.out $INVALID_LINE_FILE
echo
echo "******** testing on a file that is read by another process"
./a.out $FILE_READ
echo
echo "******** testing on a file that is written to by another process"
./a.out $FILE_WRITTEN
echo
echo "******** testing on a /root/.bashrc (access should be denied)"
./a.out $FILE_DENIED
echo
echo "******** testing on a directory"
./a.out $DIR
然后,我在下面的程序上运行了测试
$ cat test.cpp
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include <string>
int main(int argc, char* argv[]) {
if(argc != 2) {
std::cerr << "Provide one argument" << std::endl;
return EXIT_FAILURE;
}
std::ifstream fin(argv[1]);
std::istreambuf_iterator <char> eos;
std::istreambuf_iterator <char> fin_it(fin.rdbuf());
std::string str;
try {
std::copy(fin_it,eos,std::back_inserter(str));
} catch(...) {
perror("Error");
throw;
}
std::cout << str;
return EXIT_SUCCESS;
}
运行后得到如下结果:
$ ./readfile_tests.sh test.cpp
******** testing on non-existent file..
******** testing on empty file..
******** testing on valid file with one line content
rofl
******** testing on a file with one valid and one invalid line
validline
invalidline
******** testing on a file that is read by another process
i am opened to read from
******** testing on a file that is written to by another process
i am opened to write to
******** testing on a /root/.bashrc (access should be denied)
******** testing on a directory
Error: Is a directory
terminate called after throwing an instance of 'std::ios_base::failure'
what(): basic_filebuf::underflow error reading the file
./readfile_tests.sh: line 51: 22563 Aborted ./a.out $DIR
这些结果对我来说很奇怪,因为在读取目录测试时抛出异常,但在尝试读取/root/.bashrc
时没有抛出异常。因此,istreambuf_iterator 什么时候抛出异常?以防万一,我使用 gcc 4.7.3 版
。
是的,打开一个目录进行阅读是不标准的,也是不好的。同时,我需要正确地设下这个案子。根据下面的评论,这是一段尝试从目录中读取的代码:
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include <string>
void withIterators() {
std::ifstream fin("mydirectory");
if(!fin.is_open())
perror("Error opening file");
std::istreambuf_iterator <char> eos;
std::istreambuf_iterator <char> fin_it(fin.rdbuf());
std::string str;
try {
std::copy(fin_it,eos,std::back_inserter(str));
} catch(...) {
perror("Error reading file");
}
}
void noIterators() {
std::ifstream fin("mydirectory");
if(!fin.is_open())
perror("Error opening file");
std::string line;
while(getline(fin,line)) {}
if(fin.bad())
perror("Error reading file");
}
int main() {
withIterators();
noIterators();
}
运行后,我们收到输出:
Error reading file: Is a directory
Error reading file: Is a directory
这告诉我们两件事。首先,我们无法捕捉到我们在 fin
的构造函数之后将目录作为文件打开这一事实。其次,只有在使用迭代器时才会抛出异常。从目录读取时,上面的代码 noIterators
不会抛出异常。相反,它设置了 badbit。为什么代码会在一种情况下抛出异常,而在另一种情况下设置 badbit?
我从上面扩展了目录打开代码,以便更好地跟踪发生了什么
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include <string>
void withIterators() {
std::ifstream fin("mydirectory");
if(!fin.is_open())
perror("Error opening file");
std::istreambuf_iterator <char> eos;
std::istreambuf_iterator <char> fin_it(fin.rdbuf());
std::string str;
try {
std::copy(fin_it,eos,std::back_inserter(str));
} catch(...) {
perror("Error reading file");
}
}
void withIteratorsUnderflow() {
std::ifstream fin("mydirectory");
try {
fin.rdbuf()->sgetc();
} catch(...) {
perror("Error reading file");
}
}
void withOtherIterators() {
std::ifstream fin("mydirectory");
if(!fin.is_open())
perror("Error opening file");
std::istream_iterator <char> eos;
try {
std::istream_iterator <char> fin_it(fin);
} catch(...) {
perror("Error making iterator");
}
}
void noIterators() {
std::ifstream fin("mydirectory");
if(!fin.is_open())
perror("Error opening file");
std::string line;
while(getline(fin,line)) {}
if(fin.bad())
perror("Error reading file");
}
int main() {
withIterators();
withIteratorsUnderflow();
withOtherIterators();
noIterators();
}
基本上,我们会在不同的地方遇到或没有遇到异常,但出于类似的原因。
在 withIterators()
上,对 copy
的调用最终会调用代码 /usr/lib/gcc/i686-pc-linux-gnu/4.7。 3/include/g++-v4/bits/streambuf_iterator.h:187
,其中指出
else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc())
调用 sgetc()
抛出异常。很可能,这就像@user657267 所建议的那样调用下溢。
在 withIteratorsUnderflow()
上,我们看到 sgetc
直接抛出异常,这证实了 withIterators()
发生了什么。
在 withOtherIterators()
上,我们一创建 std::istream_iterator
就会抛出异常。这不同于 std::istreambuf_iterator
的情况,它直到后来才抛出异常。无论如何,在构造期间,我们调用代码 /usr/lib/gcc/i686-pc-linux-gnu/4.7.3/include/g++-v4/bits/stream_iterator.h:121
, 说明
*_M_stream >> _M_value;
基本上,istream_iterator
类在构建时创建一个 istream
,它会立即尝试读取一个字符,这会引发异常。
在 noIterators()
上,getline
只是设置 badbit 而不会抛出异常。
底线是尝试从目录中读取是不好的。有没有好的 STL(不是 boost)方法来检测这个?是否有其他情况会抛出需要捕获的特定于实现的异常?
最佳答案
istreambuf_iterator
本身永远不会抛出。
它迭代的 basic_filebuf
打开文件,就像调用 std::fopen
一样(无论它是否真的这样做都无关紧要)。
正如您在 this question 中看到的那样,标准 C 没有目录的概念,因此尝试打开一个目录是实现定义的或未定义的行为。在 gcc 的情况下(或者更确切地说是 libc),目录可以打开,但你不能用它做太多事情。
根据标准,basic_filebuf
也永远不会抛出异常,但是由于您已经通过尝试打开非文件的内容而超出了标准强制执行的范围,因此 libstdc++ 可以自由地当您尝试从目录中读取时抛出异常。
检查给定名称是否为文件通常取决于平台,但 boost::filesystem
/std::experimental::filesystem
提供可移植检查。
要回答您的编辑,您在尝试从流中读取时不会看到异常,因为哨兵将失败并且流永远不会从缓冲区中读取(最终调用 underflow
)。 istreambuf_iterator
直接在缓冲区上操作,因此没有哨兵。
事实证明,libstdc++ 不会抛出对 overflow
的类似调用,并且由于 underflow
的设置方式,不会抛出异常如果流已打开以进行写入并且 overflow
返回 eof。
关于c++ - istreambuf_iterator 什么时候抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26231837/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!