#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
#include <set>
#include <sstream>
std::string tolower( std::string str )
{ for( char& c : str ) c = std::tolower(c) ; return str ; }
std::string remove_punct( const std::string& str )
{
std::string result ;
for( char c : str ) if( !std::ispunct(c) ) result += c ;
return result ;
}
std::string capitalise( std::string str )
{ if( !str.empty() ) str[0] = std::toupper( str[0] ) ; return str ; }
// http://w...content-available-to-author-only...s.com/reference/set/set/
char* convert_to_title_case( char* title, const std::set<std::string>& nocap_words )
{
std::string converted_title ;
// http://w...content-available-to-author-only...s.com/reference/sstream/istringstream/
std::istringstream stm(title) ;
std::string word ;
while( stm >> word ) // for each word in the title
{
word = tolower(word) ;
if( !converted_title.empty() ) converted_title += ' ' ;
// capitalise it if it is not in the nocap_words set
// http://w...content-available-to-author-only...s.com/reference/set/set/find/
if( nocap_words.find( remove_punct(word) ) == nocap_words.end() )
word = capitalise(word) ;
converted_title += word ;
}
// copy converted_title back into the c-style string and return
return std::strcpy( title, converted_title.c_str() ) ;
}
std::set<std::string> get_words( std::istream& stm )
{
std::set<std::string> result ;
std::string w ;
while( stm >> w ) result.insert(w) ;
return result ;
}
int main()
{
std::istringstream minors( "a an for of the" ) ; // std::ifstream over "minors.txt"
const auto nocap_words = get_words( minors ) ;
char test[] [100] = { "a brief hisTOry OF everyTHING", "A Universal HisTOry Of infamy",
"The; history, of: punctuations!", "1024: FOR A history Of NUMBERS" } ;
for( char* title : test )
{
std::cout << title << " => " ;
std::cout << convert_to_title_case( title, nocap_words ) << '\n' ;
}
}