2012-05-11 68 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; 
}); 
相关问题