String Comparison

Hey guys, I'm writing a function that accepts a char array containing the title of a book as parameter, the following then has to take place:

1.) Extra white spaces between words need to be removed [DONE]

2.) Text has to be converted to title case, i.e each new word has to start with a capital letter [DONE]

3.) Lastly I have I text file (minors.txt) containing a number of words, each in a new line, that should not be capitalized by the function, like "a", "an" and "of", however I don't know how to implement this, any help on how to do this will be much appreciated!

Example of end product:

ENTER THE TITLE OF THE BOOK: a brief hisTOry OF everyTHING


Correct Output:

a Brief History of Everything


Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
bool Book :: convertToTitleCase(char* inTitle)
{  
      int length = strlen(inTitle);
      bool thisWordCapped = false;    
      
      //Convert paramater to lower case and
      //Remove multiple white spaces
      for (int x = 0; x < length; x++)
      {
	  inTitle[x] = tolower(inTitle[x]);
	  
	  if (isspace(inTitle[x]) && isspace(inTitle[x+1]))
	  {
	      while (isspace(inTitle[x]) && isspace(inTitle[x+1]))
	      {
		  int i;
		  for (i = x + 1; i < length; i++)
		  {
		      if(i==(length-1))
		      {
			  inTitle[i] = '\0';
		      }
		      else
		      {
			  inTitle[i] = inTitle[i+1];
		      }
		  }
	      }
	  }
      }    
     
     /* Read through text file and identify the words that should not be capitalized,
         dont know how, please help! */

     //Capitalize the first letter of each word
     for (int i = 0; i < length; i++)
      {
	  if ((ispunct(inTitle[i])) || (isspace(inTitle[i])))
	  {
	      thisWordCapped = false;
	  }
	  
	  if ((thisWordCapped==false) && (isalpha(inTitle[i])))
	  {
	      inTitle[i] = toupper(inTitle[i]);
	      thisWordCapped = true;
	  }  
      }

      return true;
}


I was thinking of maby reading the words in the text file into a string array, and then comparing the two arrays to ensure that when a word is present in a text file, the word is not capitalized, however I don't know if that is possible between a string array and a char array.

I'm quite clueless as to what to do or how it works, any help would be appreciated, thanks!

PS - I'm still relatively new to C++ so please excuse inefficient code,
Last edited on
> reading the words in the text file into a string array

Perhaps, into a std::set<> of std::string

> however I don't know if that is possible between a string array and a char array.

It is possible to compare a C++ string with a c-style string.

However, it would probably be easier to do all the processing with C++ strings, and finally copy the capitalised title into the c-style array of characters.

Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#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://www.cplusplus.com/reference/set/set/
char* convert_to_title_case( char* title, const std::set<std::string>& nocap_words )
{
    std::string converted_title ;

    // http://www.cplusplus.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://www.cplusplus.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' ;
    }
}

http://ideone.com/b53tid
Topic archived. No new replies allowed.