gpt4 book ai didi

c++ - 如何报告自定义 istream 失败

转载 作者:行者123 更新时间:2023-11-28 04:29:16 25 4
gpt4 key购买 nike

我想使用 operator>>() 从控制台读取线性代数数据。我希望 operator>>() 的行为类似于它对内置数据(如 int、double)的行为,但我也希望在无法解析输入时报告适当的消息。

我终于构建了一个“custom_istream_failure”类,但总的来说还是挺麻烦的。现在我想知道:这是要走的路,还是为此目的存在另一种机制?这符合标准的精神吗?

我已经包含了一个小的测试程序,它报告“expect”函数中的自定义失败。此外,我还包含了这个问题所涉及的“custom_istream_failure.h”头文件。

#include <iostream>
#include "custom_istream_failure.h"

struct vector_t { int x, y, z; };

bool expect(std::istream& is, char e)
{
if (is.get() != e)
{
custom_istream_failure(is)
<< "Expected '" << e << '\''
<< and_throw;
return false;
}
return true;
}

std::istream& operator>>(
std::istream& is, vector_t& v)
{
expect(is, '(') &&
(is >> v.x) &&
expect(is, ',') &&
(is >> v.y) &&
expect(is, ',') &&
(is >> v.z) &&
expect(is, ')');
return is;
}

int main()
{
try
{
std::cin.exceptions(std::istream::failbit);
vector_t vector;
std::cin >> vector;
}
catch (std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}

#ifndef CUSTOM_ISTREAM_FAILURE
#define CUSTOM_ISTREAM_FAILURE

#include <iostream>
#include <string>
#include <sstream>

class custom_istream_failure
: protected std::stringstream
{
public:
explicit custom_istream_failure(std::istream& is)
: m_is(is)
{}
custom_istream_failure& operator<<(
custom_istream_failure&
(*pf)(custom_istream_failure&))
{
return ((*pf)(*this));
}
#define CUSTOM_ISTREAM_FAILURE_SOP(D) \
custom_istream_failure& operator<<(D) \
{ \
*static_cast<std::stringstream*>(this) << v; \
return *this; \
}
CUSTOM_ISTREAM_FAILURE_SOP(bool v)
CUSTOM_ISTREAM_FAILURE_SOP(short v)
CUSTOM_ISTREAM_FAILURE_SOP(unsigned short v)
CUSTOM_ISTREAM_FAILURE_SOP(int v)
CUSTOM_ISTREAM_FAILURE_SOP(unsigned int v)
CUSTOM_ISTREAM_FAILURE_SOP(long v)
CUSTOM_ISTREAM_FAILURE_SOP(unsigned long v)
CUSTOM_ISTREAM_FAILURE_SOP(long long v)
CUSTOM_ISTREAM_FAILURE_SOP(unsigned long long v)
CUSTOM_ISTREAM_FAILURE_SOP(float v)
CUSTOM_ISTREAM_FAILURE_SOP(double v)
CUSTOM_ISTREAM_FAILURE_SOP(long double v)
CUSTOM_ISTREAM_FAILURE_SOP(void* v)
CUSTOM_ISTREAM_FAILURE_SOP(std::streambuf* v)
CUSTOM_ISTREAM_FAILURE_SOP(
std::ostream& (*v)(std::ostream&))
CUSTOM_ISTREAM_FAILURE_SOP(
std::ios& (*v)(std::ios&))
CUSTOM_ISTREAM_FAILURE_SOP(
std::ios_base& (*v)(std::ios_base&))
CUSTOM_ISTREAM_FAILURE_SOP(char v)
CUSTOM_ISTREAM_FAILURE_SOP(signed char v)
CUSTOM_ISTREAM_FAILURE_SOP(unsigned char v)
CUSTOM_ISTREAM_FAILURE_SOP(const char* v)
CUSTOM_ISTREAM_FAILURE_SOP(const signed char* v)
CUSTOM_ISTREAM_FAILURE_SOP(const unsigned char*v);
#undef CUSTOM_ISTREAM_FAILURE_SOP
private:
std::istream& m_is;
friend custom_istream_failure& and_throw(
custom_istream_failure&);
};

inline custom_istream_failure& and_throw(
custom_istream_failure& cif)
{
try { throw std::ios_base::failure(cif.str()); }
catch (...)
{
cif.m_is.setstate(std::ios::failbit, true);
}
return (cif);
}

#endif // CUSTOM_ISTREAM_FAILURE

最佳答案

一种方法是让您的类型的输入运算符处理错误情况(如下例)。如果用户希望在出错时抛出异常,setstate 将触发适当的异常。对于不希望出现异常的用户,只需以通常的方式检查输入流的状态即可。

std::istream &operator>>(std::istream &is, vector_t &v) {
char c;
if (is >> c && c == '(') {
int x = 0;
if (is >> x >> c && c == ',') {
int y = 0;
if (is >> y >> c && c == ',') {
int z = 0;
if (is >> z >> c && c == ')') {
v = {x, y, z};
return is;
}
}
}
}
is.setstate(std::ios_base::failbit);
return is;
}

关于c++ - 如何报告自定义 istream 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53362536/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com