2012-05-11 70 views
1

我正在尋找一種方法來使用增強功能在句子中對每個單詞的首字母進行大寫。 爲了使代碼保持一致,即最終輸出在輸入句子中不存在任何空格或製表符。要使用boost :: alogrithm :: split獲取單個單詞,並將它們組合到boost :: algorithm :: join中。但我如何獲得每個首字母大寫?使用增強庫大寫句子中每個單詞的首字母大寫

我想這個代碼

#include <iostream>                
#include <vector>                 
#include <boost/algorithm/string/split.hpp>          
#include <boost/algorithm/string.hpp> 

int main()                  
{                    
    using namespace std;               

    string str("cONtainS   SoMe CApiTaL WORDS");      

    vector<string> strVec;              
    using boost::is_any_of;              
    using boost::algorithm::token_compress_on;         

    boost::algorithm::split(strVec, str, is_any_of("\t "), token_compress_on); 

    vector<string>::iterator i ;             

    for(i = strVec.begin() ; i != strVec.end(); i++)        
    { 
     (*i)[0] = boost::to_upper((*i)[0]); 
     cout<<*i<<endl;                
    }                   

    return 0;                 
}  
+0

我們是在說ASCII還是應該是Unicode兼容? (提示:據我所知,Boost不支持Unicode) –

+0

截至目前我只考慮ASCII。但是,將來需要Unicode支持。 –

+0

對於Unicode,您需要一個能夠識別unicode的庫(可能像ICU一樣)來實際利用該單詞;因此分裂+加盟戰略目前成本很高,但長期來看還是有效的。 –

回答

0

此代碼讓我的工作

#include <iostream> 
#include <boost/algorithm/string.hpp> 
#include <boost/algorithm/string/trim.hpp> 
#include <vector> 
#include <ctype.h> 

int main() 
{ 
    using namespace std; 

    string str("contAins Some  CapItal WORDS"); 
    string result; 

    vector<string> strVec; 

    using boost::is_any_of; 
    using boost::algorithm::token_compress_on; 

    boost::algorithm::split(strVec, str, is_any_of("\t "), token_compress_on); 

    vector<string>::iterator i; 

    for(i = strVec.begin(); i !=strVec.end(); ++i) 
    {                     

     boost::to_lower(*i); 
     (*i)[0]=toupper((*i)[0]); 

     cout<<(*i)<<endl; 
     result += *i +" "; 
    } 

    boost::trim_right(result); 
    cout<<result; 
    return 0; 
} 
+0

我發現的問題是boost :: to_upper()需要地址不是一個值。 –

2

的問題是定義你如何判斷一個句子是什麼。最簡單的解決方案是,它是以常規 表達式"[.!?][\"\']*"結束的任何序列(因爲您已經消除了空白 空間);這實際上很簡單,您可以在沒有 正則表達式的情況下執行此操作。然後記住,你已經看到了它,並利用 下一個單詞:

bool atEndOfSentence = true; 
for (std::vector<std::string>::const_iterator current = words.begin(); 
     current != words.end(); 
     ++ current) { 
    if (atEndOfSentence) { 
     (*current)[0] == toupper((*current)[0]); 
    } 
    std::cout << *current << std::endl; 
    atEndOfSentence = isSentenceEnd( 
      *std::find_if(current->rbegin(), current->rend(), 
          IsNotQuoteChar()).base()); 
} 

有:

struct IsNotQuoteChar 
{ 
    bool operator()(char ch) const 
    { 
     return ch != '\'' and ch != '\"'; 
    } 
}; 

和:

bool 
isSentenceEnd(char ch) 
{ 
    return ch == '.' || ch == '!' || ch == '?'; 
} 
+0

嘿謝謝你回覆:)。你的代碼看起來有點複雜:P。我做了一些打擊和追蹤,並使其工作。如果你發現任何錯誤,請告訴我。 –

+0

閱讀你的代碼後。我在代碼 'boost :: to_lower(* i); (* i)[0] = toupper((* i)[0]); ' 現在它產生正確的輸出。因爲我不到100分,所以我不能在8小時前將解決方案粘貼到這裏:P –

+0

@VickeyVerma處理自然語言(書面或口語)的任何事情都會很複雜:-)。在國際環境中定義「大寫字母」的含義並不重要 - 您可能需要的是Unicode所稱的標題大小寫,而不是大寫字母。 (和FWIW:我發佈的代碼中存在一個錯誤,'toupper'的參數必須轉換爲'unsigned char',否則可能導致未定義的行爲。) –

1

我認識到,這不使用升壓並且不能用於Unicode,但是使用標準庫函數提供了一個基本的解決方案。我打破了isalpha來確定單詞的界限。也許不是最好的方式,但它只是一種替代方案:

#include <string> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    string str(" cONtainS   SoMe CApiTaL WORDS"); 

    bool niw(true); 
    string strC; 
    for (size_t i = 0; i < str.size(); ++i) 
    { 
     if (niw && isalpha(str[i])) 
     { 
      strC += toupper(str[i]); 
      niw = false; 
     } 
     else if (! niw) 
     { 
      if (isalpha(str[i])) 
       strC += tolower(str[i]); 
      else 
      { 
       niw = true; 
       strC += str[i]; 
      } 
     } 
     else 
      strC += str[i]; 
    } 

    cout << str << endl; 
    cout << strC << endl; 
} 
0

這裏是萬一有人我的C++ 11的解決方案感興趣:

std::string s("some lowercase string"); 
s[0] = toupper(s[0]); 
std::transform(s.begin()+1, s.end(),s.begin(),s.begin()+1, 
[](const char& a, const char& b) -> char 
{ 
    if(b==' ' || b=='\t') 
    { 
     return toupper(a); 
    } 
    return a; 
}); 
相關問題