2013-04-24 73 views
0

我一直试图让我的头靠近iostreams库的提升。boost :: iostreams从源设备读取

但我不能真正完全掌握这些概念。

说我有下面的类:

:以下代码是仅用于说明问题。

编辑:删除了读取的代码,因为它删除了关注真正的问题。

class my_source { 
public: 
    my_source():value(0x1234) {} 
    typedef char  char_type; 
    typedef source_tag category; 

    std::streamsize read(char* s, std::streamsize n) 
    { 
     ... read into "s" ... 
    } 
private: 
    /* Other members */ 
}; 

现在说我想流这个int。

我需要做什么?我试过以下

boost::iostreams::stream<my_source> stream; 
stream.open(my_source()); 

int i = 0; 
stream >> i; 
// stream.fail() == true; <-- ?? 

这将导致失败,(failbit设置)

虽然以下的罚款。

boost::iostreams::stream<my_source> stream; 
stream.open(my_source()); 

char i[4]; 
stream >> i;  
// stream.fail() == false; 

有人可以向我解释为什么会发生这种情况吗?这是因为我设置了char_type char?

我真的找不到任何地方的好消除。我一直在尝试阅读文档,但我无法找到char_type定义的行为,如果这是问题。虽然即时通讯使用stringstreams我可以读入一个int而不做任何特别的事情。

所以如果有人有任何见解请赐教。

回答

0

所有iostream都是文本流,所以这将采用0x1234的字节表示法,将其解释为文本并尝试将其解析为整数。

顺便说

std::streamsize read(char* s, std::streamsize n) 
{ 
    int size = sizeof(int); 
    memcpy(s, &value, 4); 
    return size; 
} 

这对于一个缓冲区溢出,如果n < 4的潜力。此外,你写四个字节,然后返回一个int的大小。 memcpy(s, &value, sizeof value);将完成这项工作,一个简单的return sizeof value;将完成剩下的工作。

+0

谢谢SteveL格式化这个。 – 2013-04-24 17:06:19

+0

@SteveL我明白,但它dosnt工作传递给一个整数,这就是整个问题。上面看到的代码只是将流传递给int的问题的简单表示。我知道并理解所有溢出问题。但我真的不明白为什么将它读入int会导致失败位,但将相同的数据读取到相同大小的结构(如char [4])。 – user2010820 2013-04-24 20:33:24

+0

假设使用ASCII编码的小端系统,开头的四字节整数0x1234将是字符序列{4,DC2,NUL,NUL}。你期望得到什么样的整数? '4'可以被解析为文本,甚至可以作为数字,但设备控制和NULs在文本字符串中没有意义。如果你使用它来读取一系列字符,它们的实际值没有任何区别,所以它可以工作。即使在上面的代码中,我也会期望缓冲区溢出。如果你想用iostreams读取原始字节,可以看看read()函数,而不是'>>'。 – 2013-04-25 05:46:31

0

boost :: iostreams ::没有参数的stream构造函数什么也不做,并且在结果流中没有打开。您需要将伪参数添加到my_source构造函数。

class my_source { 
public: 
    my_source(int fake) : value(0x1234) {} 
... 

boost::iostreams::stream<my_source> stream(0);