?
Solved

Upper case to lower case strings

Posted on 2011-05-12
6
Medium Priority
?
548 Views
Last Modified: 2012-05-11
I need help writing a function that turns a string into all lower case characters. I am using an iterator to traverse the string and I don't know how to complete/ fix this.
// filename: WordCountApp.cpp

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cctype>
using namespace std;

#include "word.h"
#include "bst2.h"

void lowerCase(string &s);

int main()
{
  ifstream fin;
  ofstream fout;

  fin.open("review.txt");
  if (!fin) 
  {
    cerr << "Input file opening error\n";
    exit(1);
  }

  fout.open("words.txt");
  if (!fout) 
  {
    cerr << "Output file opening error\n";
    exit(1);
  }

  BST<Word> bst;
  int total = 0;
  string s;

  while (fin >> s) 
  {
	  lowerCase(s);
	  total++;

	  Word *ptr;
	  ptr = bst.find(s);
	  if(*ptr != s)
		  bst.insert(s);
  }

  cout << "Total number of words read:   "
       << total << endl;
  cout << "Total number of unique words: "
       << bst.size() << endl;
  cout << endl;

  Word maxWord = bst.findMax();
  cout << "** FindMax returns \"" << maxWord.wstring << "\", "
                                  << maxWord.count << endl << endl;
  bst.printTree(fout);

  fin.close();
  fout.close();

  system("pause");
  return 0;
}

void lowerCase(string &s)
{
	string::iterator t = s.begin();

	while(*t != NULL)
	{
		if(isalpha(*t))
		{
			if(isupper(*t))
				tolower(*t);
		}
		t++;
	}
}

Open in new window

0
Comment
Question by:villmund
6 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 668 total points
ID: 35751439
Since you are using an iterator, the test

while(*t != NULL)

is the problem, that should be

while(t != s.end())

e.g.

void lowerCase(string &s)
{
	string::iterator t = s.begin();

	while(t != s.end())
	{
		if(isalpha(*t))
		{
			if(isupper(*t))
				tolower(*t);
		}
		t++;
	}
}

Open in new window

0
 
LVL 32

Accepted Solution

by:
phoffric earned 668 total points
ID: 35751530
The tolower function has prototype:
     int tolower ( int c );
"Converts parameter c to its lowercase equivalent if c is an uppercase letter and has a lowercase equivalent. If no such conversion is possible, the value returned is c unchanged."
        http://www.cplusplus.com/reference/clibrary/cctype/tolower/

From this description, you can see that the tests isalpha and isupper, while clear, are not necessary.

Notice that the input parameter c is passed by value. So, even if you thought that tolower() changes c in the function itself, inside the function, the c would be just a local variable on the tolower's call frame on the stack. That is, the lowercase value of c would not be known to the caller. The converted value is obtained by the return value.

Return Value
The lowercase equivalent to c, if such value exists, or c (unchanged) otherwise. The value is returned as an int value that can be implicitly casted to char.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 9

Assisted Solution

by:jhshukla
jhshukla earned 664 total points
ID: 35751684
phoffric did much of the explanation. in addition to jkr's loop fix, you need this:
*t = tolower(*t);

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 35754861
No need to reinvent the wheel, just use std::transform.
http://www.cplusplus.com/reference/algorithm/transform/
#include <algorithm>
#include <string>
#include <iostream>

int main()
{
   std::string s("ALL UPPER TO ALL LOWER USING TRANSFORM");
   std::transform(s.begin(), s.end(), s.begin(), ::tolower);
   std::cout << s << std::endl;
}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 35754872
Or, if you need to take locate into consideration
http://www.cplusplus.com/reference/std/locale/locale/
http://www.cplusplus.com/reference/std/functional/bind2nd/
http://www.cplusplus.com/reference/std/locale/tolower/
#include <algorithm>
#include <string>
#include <locale>
#include <iostream>
#include <functional>

struct to_lower : std::binary_function<char, std::locale, char>
{
   char operator()(char const c, std::locale const & l) const { return std::tolower(c, l); }
};

int main()
{
   std::string s("ALL UPPER TO ALL LOWER USING TRANSFORM");
   std::transform(s.begin(), s.end(), s.begin(), std::bind2nd(to_lower(), std::locale()));
   std::cout << s << std::endl;
}

Open in new window

0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Nadia
Suppose you use Uber application as a rider and you request a ride to go from one place to another. Your driver just arrived at the parking lot of your place. The only thing you know about the ride is the license plate number. How do you find your U…
Article by: Nadia
Linear search (searching each index in an array one by one) works almost everywhere but it is not optimal in many cases. Let's assume, we have a book which has 42949672960 pages. We also have a table of contents. Now we want to read the content on p…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question