- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我最近了解到可以选择加入 iostream 的异常(exception)。为了不必手动检查文件是否打开,我试过了并遇到了这种行为:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
void test(std::istream& is, bool exceptions) {
try {
if (exceptions)
is.exceptions(std::istream::failbit);
std::vector<int> input;
std::copy(std::istream_iterator<int>{is}, {}, std::back_inserter(input));
for (auto x : input) {
std::cout << x << '\n';
}
}
catch (const std::ios_base::failure& f) {
std::cerr << "Caught error: " << f.what() << '\n';
}
}
int main() {
// Emulates file
std::stringstream ss("1 2 3\n4 5 6\n7 8 9\n");
test(ss, true);
}
当异常被触发时,这会正常工作。但是当我使用异常时,我从 basic_ios::clear
中抛出了一个异常,我想不出原因。
basic_ios::clear
没有列在根据cppreference 可以设置failbit
的函数下.
提前致谢。
编辑: 下面的答案已经回答了为什么会发生这种情况。我现在的附加问题是如何避免这种异常?我的第二次尝试是用这个循环替换 std::copy
:
for (int n; is >> n;) {
input.push_back(n);
}
产生了同样的异常。还是这种行为是有意为之的?
注意:clang 不会显示此行为。
最佳答案
使用 GDB,您可以看到当 std::istream_iterator
递增时发生错误。
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff71d13fa in __GI_abort () at abort.c:89
#2 0x00007ffff7ae80ad in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7ae6066 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7ae60b1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7ae62c9 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7b0eea3 in std::__throw_ios_failure(char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff7b4a82d in std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00007ffff7b4d52f in std::istream::operator>>(int&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#9 0x00005555555556c2 in std::istream_iterator<int, char, std::char_traits<char>, long>::_M_read (this=0x7fffffffe230) at /usr/include/c++/6/bits/stream_iterator.h:121
#10 0x0000555555555ac2 in std::istream_iterator<int, char, std::char_traits<char>, long>::operator++ (this=0x7fffffffe230) at /usr/include/c++/6/bits/stream_iterator.h:95
#11 0x0000555555555a36 in std::__copy_move<false, false, std::input_iterator_tag>::__copy_m<std::istream_iterator<int, char, std::char_traits<char>, long>, std::back_insert_iterator<std::vector<int, std::allocator<int> > > > (__first=..., __last=..., __result=...) at /usr/include/c++/6/bits/stl_algobase.h:293
#12 0x0000555555555965 in std::__copy_move_a<false, std::istream_iterator<int, char, std::char_traits<char>, long>, std::back_insert_iterator<std::vector<int, std::allocator<int> > > > (__first=..., __last=..., __result=...) at /usr/include/c++/6/bits/stl_algobase.h:386
#13 0x00005555555557e2 in std::__copy_move_a2<false, std::istream_iterator<int, char, std::char_traits<char>, long>, std::back_insert_iterator<std::vector<int, std::allocator<int> > > > (__first=..., __last=..., __result=...) at /usr/include/c++/6/bits/stl_algobase.h:424
#14 0x00005555555554c9 in std::copy<std::istream_iterator<int, char, std::char_traits<char>, long>, std::back_insert_iterator<std::vector<int, std::allocator<int> > > > (__first=..., __last=..., __result=...) at /usr/include/c++/6/bits/stl_algobase.h:456
#15 0x00005555555550ed in test (is=..., exceptions=true) at sample.cpp:12
#16 0x000055555555521c in main () at sample.cpp:25
展开循环,可以发现问题是最后一次调用increment,即在输入流为空时调用std::istream_iterator::operator++
。
仔细观察堆栈跟踪,最后的增量是在流为空时尝试 std::istream::operator>>。根据 cppreference 的说法,这将导致 failbit 被设置,因为该操作无法从流中提取整数。
关于c++ - iostream 上的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056624/
在 C++ 中包含头文件时,和...有什么区别 在 <> 标志中包含 .h 部分与不包括 .h 部分? #include 与 #include 将标题名称用双引号括起来还是用 符号括起来? #inc
最近我在阅读 Accelerated C++ 并从练习答案中发现了这个有趣的代码。这是完整的代码, #include "stdafx.h" #include "4_4.h" #include usi
我正在开发一个需要能够在标准 C++ 编译器和准标准编译器上编译的实用程序。代码可以而且将会被扔到几乎任何现有的 C++ 编译器上。 我正在寻找一种可靠且可移植地确定目标编译器是否支持带或不带 .h
如果有一个文件 foo.cpp,那么它通常有一个关联的头文件 foo.h,其中包含 foo.cpp 中定义的函数的所有声明。这样,所有其他使用 foo.cpp 中的函数的文件都可以只包含 foo.h
iostream 和 iostream.h 有什么区别? 最佳答案 iostream.h 已被提供它的编译器弃用,iostream 是 C++ 标准的一部分。 为了明确说明,当前 C++ 标准 (IN
我知道关于 之间的区别的问题和 之前有人问过。阅读这些答案后,我发现了以下差异 当然iostream.h已弃用,新的符合标准的编译器不支持它 iostream.h不包含 std 中的所有内容命名
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Difference between iostream and iostream.h 我的教授说了以下内容:
我需要构建一些我在办公室电脑上得到的旧代码,它有 gcc 4.4.5安装。我编辑了代码(删除 .h 或添加类似 的内容)以使它们保持最新,以便它们可以由 gcc 4.4.5 编译.但是,在看似成功编
我在学习C++的时候遇到了一个问题,在编译的时候遇到了错误。 详情如下: 最佳答案 您似乎没有在 MinGW 中安装 C++ 支持。如果您使用手动安装路径,请下载 gcc-c++ dev、dll 和
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: What is the difference between #include and #include
对于我当前的任务,我需要能够读/写(主要是基于文件的)比特流。虽然如果用标准 C/C++ 编码,这或多或少是一项微不足道的任务,但我喜欢通过重载和使用更通用的方法重写代码标准的 STL iostrea
这个问题在这里已经有了答案: Difference between iostream and iostream.h (3 个答案) 关闭 9 年前。 有什么区别 #include 和 #inclu
我正在尝试为 linux/MacOS 转换一个用 C++14 编写的应用程序。它使用 boost::filesystem,但不用于某些 iostream 操作。例如: boost::filesyste
示例: namespace boostio = boost::iostreams; boostio::stream memStream(arr); while (!memStream.eof())
我编写了以下简单的 C++ 程序: #include using namespace std; int main() { cout ^~~~~~~~~~ 1 error
我想在我的代码中将流公开为它们的标准等价物,以消除用户对 boost::iostreams 的依赖性.如果有必要,当然想有效地执行此操作而无需创建拷贝。我考虑过只设置 std::istream的缓冲区
#include in header files and #include only in cpp files 被认为是最佳实践。我正在尝试将大量 #include 从 header 移动到现有
#include #include #include #include using namespace std; int main() { int ival; while(ci
假设我得到一个 stringbuf,其中包含一些必须删除的特定字符序列的内容: std::stringbuf string_buff; std::iostream io_stream (&string
我有一个包含如下记录的文件 123 Tag 现在是所有好人都来帮忙的时候了 总是有一个数字和一些标签,后面跟着一系列单词。我想将数字提取为整数,将标记提取为字符串,将句子提取为字符串。我已经使用 ge
我是一名优秀的程序员,十分优秀!