几天前,我正在研究 istream 迭代器和异常处理,我对此感到好奇:
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[])
{
if (argc < 2) {
cout << argv[0] << " <file>" << endl;
return -1;
}
try {
ifstream ifs(argv[1]);
ifs.exceptions(ios::failbit | ios::badbit);
istream_iterator<string> iss(ifs), iss_end;
copy(iss, iss_end, ostream_iterator<string>(cout, "\n"));
}
catch (const ios_base::failure& e) {
cerr << e.what() << endl;
return -2;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么在读取输入文件的最后一个字后总是引发失败位异常?
对于我自己的小解析器框架,我试图定义(类似)以下函数:
template <class T>
// with operator>>( std::istream&, T& )
void tryParse( std::istream& is, T& tgt )
{
is >> tgt /* , *BUT* store every character that is consumed by this operation
in some string. If afterwards, is.fail() (which should indicate a parsing
error for now), put all the characters read back into the 'is' stream so that
we can try a different parser. */
}
Run Code Online (Sandbox Code Playgroud)
然后我可以这样写:(也许不是最好的例子)
/* grammar: MyData = <IntTriple> | <DoublePair>
DoublePair = <double> <double>
IntTriple …Run Code Online (Sandbox Code Playgroud) std::istream有原型读取istream& read (char* s, streamsize n)的实际字节数应该通过调用获得istream::gcount(),也istream可以从中获知有效性ios::good.
我正在和我的一位同事讨论另一个流类的实现,我在那里说我可能会遵循这个设计; 但他说,不是让用户每次都调用gcount,而是可以读取这样的原型,这样istream& read (char* s, streamsize n, size_t &bytes_read)它就可以在一次调用中完成,而前者是笨拙的.我无法捍卫std自己的设计选择.背后的真正理由是istream::read什么?
我正在尝试创建一个istream直接从原始内存缓冲区读取的内容.
我在这里的另一篇文章中找到了一个很好的方法:
class membuf : public basic_streambuf<char>
{
public:
membuf(char* p, size_t n) {
setg(p, p, p + n);
}
};
Run Code Online (Sandbox Code Playgroud)
然后我创建我istream使用这个membuf:
membuf mb(dataPointer, dataLength);
istream reader(&mb);
Run Code Online (Sandbox Code Playgroud)
然后我阅读使用getline()和>>运算符,一切都很棒.但是,我似乎无法seekg()回退到缓冲区的开头,并且istream::tellg()总是返回-1.
我是否需要编写更多代码才能使这些代码发挥作用,或者这注定要失败?
因此,我一直试图弄清楚如何等待来自 C++ stringstream 的数据(例如),而不需要不断检查数据是否存在,这非常消耗 CPU。
例如,我完全能够从串行设备读取数据,并在没有数据到达时锁定进程,但不幸的是我无法弄清楚如何使用 C++ 流来做到这一点。
我确信我错过了一些东西,因为 cin 正是这样做的,即等待返回键从 istream 读取中退出,但它是如何做到的呢?
预先感谢您对这个主题的任何了解。
我发现了一张C-ISH C++代码,并问自己(略学术)的问题,有什么隐式类型转换发生在这里,以在到达bool该if要求?
int val;
if( (std::cin >> val) == 0 )
...
Run Code Online (Sandbox Code Playgroud)
我到目前为止:
std::cin >> val返回(参考)cin,因此istream&==接收cin和0作为操作数,即istream和int我认为没有bool operator==(istream&, int)可用的(也没有相应的成员函数istream),所以是否涉及转换?
为了清楚起见,程序员的意图是检查输入是否成功,即应该写入if(!(std::cin >> val)).
是否有任何简单的机制可以使用 C++ 输入流(如ifstream)跳过直到下一个空格?
我知道ignore如果我知道要跳过多少个字符或需要什么分隔符,我就可以使用它。ignore但在我看来,当operator>>通常只是读取下一个空白而不提供任何其他参数时,使用起来很丑陋。我也可以使用假人,但这只会让事情变得更糟。
auto importantInfo1 = 0;
auto importantInfo2 = 0;
auto someDummy = 0; // This is ugly and doesn't clearly express the intent
file >> importantInfo1 >> someDummy >> importantInfo2;
Run Code Online (Sandbox Code Playgroud)
另外,在某些情况下,如果我需要在“跳过”情况下处理不同的数据类型,我将需要多个虚拟对象。
我会想象这样的事情:
file >> importantInfo1;
file.skip<int>(1);
file >> importantInfo2;
Run Code Online (Sandbox Code Playgroud)
或者甚至更好:
auto importantInfo1 = 0;
auto importantInfo2 = 0;
file >> importantInfo1 >> skip<int> >> importantInfo2;
Run Code Online (Sandbox Code Playgroud)
我想这样的解决方案也会比实际解析值并将其存储在不需要的地方更好。
使用提供的答案制定了此解决方案。与接受的答案基本相同,但不需要临时。相反,它会跳过第一个空格,然后跳过除空格之外的任何字符,直到再次到达空格为止。此解决方案可能使用 2 个 while 循环,但不需要了解提取的类型。我并不是说这是一个高性能解决方案或任何奇特的解决方案,但它使生成的代码更短、更干净且更具表现力。
template<typename CharT, typename Traits>
inline std::basic_istream<CharT, …Run Code Online (Sandbox Code Playgroud) 我有一个IStream,我知道它包含一个 PNG 文件,但我无法像普通 I/O 流一样将其内容写入文件,我不知道我是否做错了什么,或者我应该做不同的事情将IStream写入文件。
IStream *imageStream;
std::wstring imageName;
packager.ReadPackage(imageStream, &imageName);
std::ofstream test("mypic.png");
test<< imageStream;
Run Code Online (Sandbox Code Playgroud) 我希望能够解决这样的问题:Getting std::ifstream to handle LF, CR, and CRLF? 其中 anistream需要通过复杂的分隔符进行标记;这样标记化的唯一方法istream是:
istream一次读取一个字符正则表达式非常擅长用复杂的分隔符标记字符串:
string foo{ "A\nB\rC\n\r" };
vector<string> bar;
// This puts {"A", "B", "C"} into bar
transform(sregex_iterator(foo.cbegin(), foo.cend(), regex("(.*)(?:\n\r?|\r)")), sregex_iterator(), back_inserter(bar), [](const smatch& i){ return i[1].str(); });
Run Code Online (Sandbox Code Playgroud)
但我不能regex_iterator在 a 上使用 a istream:( 我的解决方案是吸食istream然后运行regex_iterator它,但吸食步骤似乎是多余的。
是否存在istream_iterator和 的邪恶组合regex_iterator,或者如果我想要它,我必须自己编写它吗?
显然,C++20 有一个新的std::istream相关构造:std::istream_view。其上的 cppreference 页面现在是一个存根\xe2\x80\xa0。那么,什么是“视图istream”以及我可以用它做什么?
\xe2\x80\xa0 - 好吧,从技术上讲,它重定向到一个关于该std::basic_istream_view存根的页面。