не може да извлече двойно от низ без значение за главни и малки букви?

Опитвам се да измисля низ без значение за главни и малки букви и намерих следното в мрежата

http://www.gotw.ca/gotw/029.htm

Така че основно моят код, за да измисля низ, който не е чувствителен към главни и малки букви, е както следва

struct ci_char_traits : public std::char_traits<char> {

    static bool eq( char c1, char c2 )
    { return toupper(c1) == toupper(c2); }

    static bool ne( char c1, char c2 )
    { return toupper(c1) != toupper(c2); }

    static bool lt( char c1, char c2 )
    { return toupper(c1) <  toupper(c2); }

    static int compare(const char* s1, const char* s2, size_t n )
    { return memicmp( s1, s2, n ); }

private:
    static int memicmp(const void *s1, const void *s2, size_t n) {

        if (n != 0) {
            const unsigned char *p1 = (const unsigned char *)s1, *p2 = (const unsigned char *)s2;
            do {
                if (toupper(*p1) != toupper(*p2))
                    return (*p1 - *p2);
                p1++;
                p2++;
            } while (--n != 0);
        }
        return 0;
    }
};

// case insensitive string type definition
typedef std::basic_string<char, ci_char_traits> ci_string;

// provide standard output for case insensitive string
template<typename char_type, typename traits_type, typename allocator_type>
inline std::basic_ostream<char_type, traits_type>&
operator<<(std::basic_ostream<char_type, traits_type>& os,
           const std::basic_string<char_type, ci_char_traits, allocator_type>& str) {
    return std::__ostream_insert(os, str.data(), str.size());
}

така че дефиницията на типа е низът. Сега проблемът, който имам, е, че не мога да накарам функция да работи с този персонализиран низ, тъй като работи с обикновен низ. Следната шаблонна функция получава стойност от низа, но

template <typename T, class string_type, typename counter_type>
T stream_cast(const string_type& s) {

  typedef typename string_type::value_type char_type;
  typedef typename string_type::traits_type traits_type;

  typename std::basic_istringstream<char_type, traits_type> iss(s);

  T x;
  char c;
  if (!(iss >> x) || iss.get(c))
     cout<<"*** ERROR *** Bad Conversion!"<<endl;
  return x;
} 

Извиквам тази функция, за да получа двойно от низ, както следва:

ci_string str("2.0");
double test = stream_cast<double>(str);

Но нещо не е наред с моята дефиниция на нечувствителен към регистър низ, защото оценката на обекта на потока чрез оператор! винаги се проваля (редът !(iss >> x) винаги е верен за този тип низ).

Някой знае ли защо имам този проблем? Благодаря предварително, че отделихте време да прочетете тази дълга публикация.

aa


person aaragon    schedule 09.10.2011    source източник
comment
Предполагам, че всички основни операции за форматиране са дефинирани само за char_traits<char>, така че тези претоварвания просто не съществуват. Можете да заобиколите това, като използвате обикновени низове за I/O и просто конструирате един низ от друг (напр. ci_string is(s.begin(), s.end()); и т.н.).   -  person Kerrek SB    schedule 09.10.2011
comment
Интересно нещо: кодът, компилиран с VC++ 2010, работи според очакванията, но когато се компилира с gcc 4.5.3, се сблъсква с горния проблем.   -  person Eugene    schedule 09.10.2011
comment
Току-що прекарах още 2 часа, опитвайки се да разбера защо се случва това. Badbit е зададен за този тип низ, но нямам представа защо. Опитах се да напиша моя собствена версия на функцията basic_istream‹_CharT, _Traits›::_M_extract, но в един момент спрях, защото нямах достъп до защитени членове на класа basic_istream. Това ме подлудява... =/   -  person aaragon    schedule 10.10.2011


Отговори (1)


Написахте потребителски изходен оператор "operator>>", но не и входен оператор "operator‹‹", а това е този, от който се нуждаете.

Това работи чудесно:

ci_string str("2.0");
std::cout << str << std::endl;

заради оператора>>.

Но

std::cin >> str

не.

person Marshall Clow    schedule 10.11.2011
comment
Благодаря на Маршал за отговора. Ще се опитам да се върна към тази част от кода и да добавя оператора. Не бих разбрал това сам. - person aaragon; 19.01.2012