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 2010-05-16 09:54  csbird  阅读(5779)  评论(0编辑  收藏  举报