bird

统计

留言簿(1)

Friends

阅读排行榜

评论排行榜

自定义C++流的分隔符

    C++输入流的默认分隔符是空格和回车。在某些场合,输入数据会以其他字符作为分隔符,如‘,’,‘;’等。通常我们可以将数据读入后再处理;STL则提供了一些方法使得我们可以在流这一层面上就进行过滤。
    C++的流处理都是与locale(本地化)相关的,每个locale包含了如何处理数值(numeric)、时间和日期(time)、货币(monetary)、字符的分类和转换(ctype)等信息。STL将这样的每个类别称为facet。
    现在我们期望输入流能够将自定义的字符如‘,’识别为空格,这属于字符分类的处理。可通过继承STL中的ctype<>来实现自定义的字符分类。代码如下:
//FilterCharacter.h
#include <locale>

class FilterCharacter : public std::ctype<char>
{
public:
   
//chars包含用户自定义的分隔字符
    FilterCharacter(const std::string& chars);

private:
    std::ctype_base::mask 
const* getTable(const std::string& chars);
};

//FilterCharacter.cpp

//这里的true参数指明当FilterCharacter实例被销毁时,自动销毁getTable中生成的table
//也可以为false,表明当该FilterCharacter的引用计数为0时才销毁table
FilterCharacter::FilterCharacter(const std::string& chars) : std::ctype<char>(getTable(chars), true)
{
}


std::ctype_base::mask 
const* FilterCharacter::getTable(const std::string& chars)
{
    std::ctype_base::mask
* table = new std::ctype_base::mask[std::ctype<char>::table_size];
    std::fill_n(table, std::ctype
<char>::table_size, std::ctype_base::mask());
    
for(int i = 0; i < chars.size(); ++i)
    {
       
//将用户自定义的字符分类为空格
        table[chars[i]] = std::ctype_base::space;
    }
    
return table;
}

有了这样一个ctype facet,将其安装到输入流的locale中,就可实现自定义分隔符。来看一个简单应用。
int main()
{
     std::string name, age;

     //将逗号和分号作为分隔符
     FilterCharacter filter(";,");

     //安装包含有自定义的的ctype的locale到输入流中
     std::cin.imbue(std::locale(std::locale(), &filter));

     
while (std::cin >> name >> age)
        std::cout 
<< "name:'" << name << "'\n"
                  
<< "age: '" << age << "'\n";
}

参考资料:
《The C++ Standar Library》

posted on 2007-12-01 11:42 csbird 阅读(2024) 评论(2)  编辑 收藏 引用

评论

# re: 自定义C++流的分隔符 2008-01-25 23:21 daidb

为何你的代码不能读取浮点数?
float r;
cin>>r;//读不到  回复  更多评论   

# re: 自定义C++流的分隔符 2008-01-26 15:34 csbird

@daidb

经测试,上述代码是可以正确读取浮点数的。
我的运行环境:VC2008 express  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理