#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' ;
    }
}
