2014-04-04 1 views
0

가상 함수 do_is()을 재정의하기 위해 ctype 클래스를 파생시켜 내 자신의 패싯을 작성했습니다. 제 목적은 스트림 추출기가 공백 문자를 무시하도록하는 것입니다 (여전히 도표화 문자에서 토큰 화합니다). 이 오버 라이딩은 마더 클래스의 구현을 호출합니다. 그러나 wchar_t으로 컴파일됩니다. char 템플릿 값에 대해서는 ctype::do_is()을 구현하지 않습니다. gcc 및 VS 2010에 해당합니다.facet ctype, do_is() 및 특수화

다음은 제 코드입니다. 두 버전 간 테스트를 수행하려면 5 행의 주석 처리를 제거하면됩니다.

#include <iostream> 
#include <locale> 
#include <sstream> 

// #define WIDE_CHARACTERS 

#ifdef WIDE_CHARACTERS 
typedef wchar_t CharacterType; 
std::basic_string<CharacterType> in = L"string1\tstring2 string3"; 
std::basic_ostream<CharacterType>& consoleOut = std::wcout; 
#else 
typedef char CharacterType; 
std::basic_string<CharacterType> in = "string1\tstring2 string3"; 
std::basic_ostream<CharacterType>& consoleOut = std::cout; 
#endif 

struct csv_whitespace : std::ctype<CharacterType> 
{ 
    bool do_is(mask m, char_type c) const 
    { 
     if ((m & space) && c == ' ') 
     { 
      return false; // space will NOT be classified as whitespace 
     } 

     return ctype::do_is(m, c); // leave the rest to the parent class 
    } 
}; 

int main() 
{ 
    std::basic_string<CharacterType> token; 

    consoleOut << "locale with modified ctype:\n"; 
    std::basic_istringstream<CharacterType> s2(in); 
    s2.imbue(std::locale(s2.getloc(), new csv_whitespace())); 
    while (s2 >> token) 
    { 
     consoleOut << " " << token << '\n'; 
    } 
} 
+0

무엇이 당신 질문입니까? 좁은 문자 스트림은 분류를 위해 테이블 ​​조회를 사용합니다. 구현은'char' 이외의 문자 유형에서만 작동합니다. – 0x499602D2

답변

0

좁은 문자 스트림은 분류를 위해 테이블 ​​조회를 사용합니다 (나는 최적화 이점이라고 생각합니다). 귀하의 구현은 char 이외의 문자 유형에서만 작동합니다. C++ reference page에서 테이블을 사용하여 문자를 분류하는 방법을 볼 수 있습니다.

1

고맙습니다!

내가 제공 한 링크에서 다음 코드를 수행했는데 제대로 작동합니다.

#include <iostream> 
#include <vector> 
#include <locale> 
#include <sstream> 

// This ctype facet declassifies spaces as whitespace 
struct CSV_whitespace : std::ctype<char> 
{ 
    static const mask* make_table() 
    { 
     // make a copy of the "C" locale table 
     static std::vector<mask> v(classic_table(), classic_table() + table_size); 

     // space will not be classified as whitespace 
     v[' '] &= ~space; 

     return &v[0]; 
    } 

    CSV_whitespace(std::size_t refs = 0) : ctype(make_table(), false, refs) {} 
}; 

int main() 
{ 
    std::string token; 

    std::string in = "string1\tstring2 string3"; 

    std::cout << "locale with modified ctype:\n"; 
    std::istringstream s(in); 
    s.imbue(std::locale(s.getloc(), new CSV_whitespace())); 
    while (s >> token) 
    { 
     std::cout << " " << token << '\n'; 
    } 
}