2011-10-09 11 views
1

我想拿出一個區分大小寫字符串,我在網上找到了以下無法從不區分大小寫的字符串中提取double?

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

+0

我想所有的基本格式化操作只是爲'char_traits '定義的,所以那些重載根本不存在。你可以通過使用普通的字符串來處理I/O,並從另一個字符串構造一個字符串(例如'ci_string is(s.begin(),s.end());'等等)。 –

+0

有趣的事情:用VC++ 2010編譯的代碼按預期運行,但用gcc 4.5.3編譯時遇到上述問題。 – Eugene

+0

我只花了2個小時試圖找出爲什麼會發生這種情況。 badbit是爲這種類型的字符串設置的,但我不知道爲什麼。我試圖編寫我自己的函數basic_istream <_CharT,_Traits> :: _ M_extract,但是在某些時候我停止了,因爲我無法訪問basic_istream類的受保護成員。 這讓我發瘋...... =/ – aaragon

回答

1

你寫了一個自定義輸出操作「操作符>>」,而不是輸入運營商「運營商< <」,這就是你需要的。由於運營商的

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

>>:

這個偉大的工程。

std::cin >> str 

沒有。

+0

感謝馬歇爾回覆。我會嘗試回到那段代碼並添加運算符。我本人不會想到這一點。 – aaragon

相關問題