C++ Sentence Case (Capitalize First Word)

when typing up important documents, it is important to use sentence case to invoke a sense of formality. imagine writing an email or heck, an entire blog post, not using a capital letter. it would really hurt your professional decorum. So this post will show you how to convert a string to sentence case using C++. Sentence case is having the first letter of the first word in a sentence capitalized. Download the Source Code

The Code

//Joseph McCullough
//Program: sentencecase.cpp
//Description: Converts a string to sentence case.
//Visit http://www.mcculloughdesigns.com for more C++ Goods

#include <iostream>
#include <string>
using namespace std;

void sentenceCase(string&);
void lowerCase(string&);
bool isSentencePunc(char);

const string SENTINEL = "0";//When entered as strToConvert,
              //terminates program.

int main()
{
  string strToConvert;    //The string that will be converted

  cout << "***************************************************" << "\n"
     << "SentenceCase.exe"                     << "\n"
     << "Converts Strings to Sentence Case" << "\n"
     << "Provided By McCullough Designs"      << "\n"
     << "***************************************************";

  //Read in strToConvert
  cout << "\n\nEnter a String or enter 0 to exit: ";
  getline(cin, strToConvert);

  while (strToConvert != SENTINEL)
  {
    sentenceCase(strToConvert);
    cout << "New String: " << strToConvert;

    //Read in strToConvert
    cout << "\n\nEnter a String or enter 0 to exit: ";
    getline(cin, strToConvert);

  }
  return 0;
}

/****** function sentenceCase *****
Description: Converts a string so that the first letter of the first word
of a sentence is capitalized.

PARAMETERS
  strToConvert: the string being manipulated

Precondition:
  strToConvert: undefined

  HEADERS
  #include <string>

Postcondition:
  Returns the manipulated string by reference */

void sentenceCase(string& strToConvert)
{
  //Identifies if the sentence has been capitalized. Set to false by default.
  bool thisSentenceCapped = false;
  lowerCase(strToConvert);  //Lowercase the string before processing.

  for (unsigned int i=0; i<strToConvert.length();i++)
  {
    //At a punctuation mark, the next sentence has not been manipulated
    //yet to have its first letter capitalized, so thisSentenceCapped is false.
    if (isSentencePunc(strToConvert[i]))
      thisSentenceCapped = false;

    if ((thisSentenceCapped==false) && (isalpha(strToConvert[i])))
    {
      strToConvert[i]=toupper(strToConvert[i]);
      thisSentenceCapped = true;
    }

  }
}

/****** function lowerCase *****
Description: makes all the characters of a string lowercase

PARAMETERS
  strToConvert: the string being manipulated

Precondition:
  strToConvert: undefined

  HEADERS
  #include <string>

Postcondition:
  Returns the string all lowercase */

void lowerCase(string& strToConvert)
{
   for(unsigned int i=0;i<strToConvert.length();i++)
   {
      strToConvert[i] = tolower(strToConvert[i]);
   }
}

/****** function isSentencePunc *****
Description: Checks to see if a character is a punctuation mark used to denote
the end of a sentence. (! . ?)

PARAMETERS
  character: The character being tested

Precondition:
  character: defined

Postcondition:
  Returns boolean value of true if the character is ! . or ? */

bool isSentencePunc(char character)
{
  switch(character)
  {
    case '!':
    case '.':
    case '?':
      return true;
    default:
      return false;
  }
}
Download the Source Code

The Explanation

You'll notice the logic for the sentenceCase function is very similar to the logic of the capEachWord (proper case) function. To understand sentence case, we must first understand a sentence. So what is a sentence? In English, a sentence is a series of alphanumeric characters, punctuation marks, and blank spaces followed by a period, exclamation point, or question mark. Once we have come across one of these three characters, we know the current sentence has ended and the next sentence is about to begin. C++ has a standard function for evaluating if a character is a punctuation mark via ispunct(). However, this function includes every punctuation mark: Colons, commas, hyphens, things that usually do not denote the end of a sentence. For this reason, we have to make our own function.
bool isSentencePunc(char character)
{
  switch(character)
  {
    case '!':
    case '&':
    case '?':
      return true;
    default:
      return false;
  }
}
The function takes in a character by value, and returns true if the character is an exclamation point, period, or question mark. The function returns false if otherwise. The sentenceCase function starts out by lowercasing the string. We do this so random capital letters within words will be accounted for.
This IS Not sentence Case.
This iS not  sentence case.
However, this brings up a problem: What about proper nouns? The following sentence is sentence case.
My name is Joseph.
In order to accommodate for proper nouns, we would have to have a library or database with all the proper nouns known. For simplicities sake, we'll omit that process. Now on to the sentenceCase function itself. thisSentenceCapped is a boolean variable set to false by default. As the name implies, this keeps track of whether the current sentence being processed has been capitalized. thisSentenceCapped is set to false by default so that if the first character of a string happens to be a letter, it will be capitalized. When thisSentenceCapped is false and the current character being processed in the forloop is a letter, the letter is uppercased using the standard character toupper() function. At that point, thisSentenceCapped is set to true, and the loop moves on to the next character. The loop will not uppercase any letters until thisSentenceCapped is set to false. thisSentenceCapped will not be set to false until a period, exclamation point, or question mark is found (in other words, when isSentencePunct() evaluates to TRUE). Here is a visualization using the sentence:
"dude, Where’s my Car? i don’t Know man.
With proper sentence case applied, the sentence should read
"Dude, where's my car? I don't know man."
So here we are, starting off: thisSentenceCapped is set to false. C++ Sentence Case Step 1 Now we lowercase all the letters before processing. C++ Sentence Case Step 2 We begin to process the first character. Since thisSentenceCapped is false and the current character is a letter, we uppercase the letter and set thisSentenceCapped to true. C++ Sentence Case Step 3 thisSentenceCapped is true, we will move through each character until we come across a sentence punctuation mark (. ? !) C++ Sentence Case Step 4 C++ Sentence Case Step 5 C++ Sentence Case Step 6 Although the comma is a punctuation mark, it is not a sentence punctuation of a period, question mark, or exclamation point, so isSentencePunc still evaluates to false, and thisSentenceCapped is still true. C++ Sentence Case Step 7 Blank spaces do not denote the end of a sentence, so thisSentenceCapped is still true C++ Sentence Case Step 8 C++ Sentence Case Step 9 C++ Sentence Case Step 10 C++ Sentence Case Step 11 C++ Sentence Case Step 12 C++ Sentence Case Step 13 C++ Sentence Case Step 14 C++ Sentence Case Step 15 C++ Sentence Case Step 16 C++ Sentence Case Step 17 C++ Sentence Case Step 18 C++ Sentence Case Step 19 C++ Sentence Case Step 20 C++ Sentence Case Step 21 C++ Sentence Case Step 22 We come across a question mark, which makes isSentencePunc evaluate to true. This causes thisSentenceCapped to become false. C++ Sentence Case Step 23 Although thisSentenceCapped is false, the function calls for the character to be alphabetical (via isalpha()), so the blankspace is not uppercased and thisSentenceCapped remains false. C++ Sentence Case Step 24 Since thisSentenceCapped is false, and the current character is alphabetical, we uppercase the letter and set thisSentenceCapped to true. C++ Sentence Case Step 25 After this point, there will be no visible changes since this is the last sentence being processed in the string. The loop will continue to process the string, but no changes will occur until the period, in which thisSentenceCapped is set to false and the loop terminates. Download the Source Code This concludes how to manipulate a string to sentence case in C++. March 21, 2010
About the Author:

Joseph is the lead developer of Vert Studios Follow Joseph on Twitter: @Joe_Query
Subscribe to the blog: RSS
Visit Joseph's site: joequery.me