首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何报告自定义istream故障

如何报告自定义istream故障
EN

Stack Overflow用户
提问于 2018-11-18 15:33:30
回答 1查看 164关注 0票数 0

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

我最终构建了一个‘custom_istream_failure’类,但所有这些都是非常麻烦的。现在我想知道,这是一条路,还是有另一种机制来达到这个目的?这是否符合标准的精神?

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

代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
#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
EN

回答 1

Stack Overflow用户

发布于 2018-11-18 16:23:12

一种方法是让输入操作符为您的类型处理错误条件(例如下面的例子)。如果用户希望在出现错误时抛出异常,setstate将触发适当的异常。对于不需要异常的用户,只需以通常的方式检查输入流的状态。

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53362536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档