Solved

C++ string manip help!!!!

Posted on 2013-11-07
8
578 Views
Last Modified: 2013-11-11
Hello all,

In my mission to learn c++ I ran into a roadblock yet again. I got most everything working and just need some guidance on the last part. Also, the code im attaching works great in xcode but for soem reason comes up short with a couple errors in visual studio. Not sure why this happens either.

Basically I need to take a user input string and loop until the user types quit. While looping I change the string to upper case, output it, change the string to lowercase, outputit it, display it in proper case output it, sort it in ascii form then output it anb finally sort it alphabetically then output it. The program outputs all the transformation on screen at same time.

I have 3 problems, First, my function for the proper case  is displaying the result twice. I think it has something to do with the do loop in the beginning. Secondly, I have no idea how to start the alpha sort and thirdly, why does this work in xcode and not Visual studio. I dont see anything out of the ordinary here. I commented all the code to help organize it.

Thanks in advance for all your help.

//libraries to be used
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
#include <locale>

using namespace std;

//prototypes defined
string proper(string name);
string sort(string name);

int main()
{
    //name variables being used
    string name;
    
    //do loop will run as long as while statement is true
    do
    {
        cout << "Please enter your name (or quit to exit): ";
        
        getline(cin, name);
        
        //changes string to uppercase
       transform(name.begin(), name.end(), name.begin(), ::toupper);
        
        if(name == "QUIT")
        {
            cout << "\nGoodbye!" << endl;
            return EXIT_SUCCESS;
        }
        
        else
        {
            //changes string to upper case
            transform(name.begin(), name.end(), name.begin(), ::toupper);
            cout << "\nYour name in upper case is: " << name << endl;
            
            //changes string to lower case
            transform(name.begin(), name.end(), name.begin(), ::tolower);
            
            //displays string in lower case
            cout << "\nYour name in lower case is: " << name << endl;
            
            //displays string in proper case
            cout << "\nYour name in proper case is: " << proper(name) << endl;
            
            //displays string in ASCII sort
            cout << "\nYour name in ASCII sort is: " << sort(name) << endl;
            
            //displays string in Alpha sort
            cout << "\nYour name in Alpha sort is: " << '\n' << endl;
            
        }
        
    }

    //when name == "QUIT", the 'do' loop will stop
    while (name != "QUIT");

    //returns a successful exit
    return EXIT_SUCCESS;
}

//function to display string in proper case
string proper(string name)
{
    long l = name.length();
    name[0] = toupper(name[0]);
    cout << name[0];
    
    for(int i = 1; i < l; i++)
    {
        if(name[i] != ' ')
        {
            cout << name[i];
            continue;
        }
        
        if(name[i] == ' ')
        {
            cout << ' ';
            
            i++;
            
            name[i] = toupper(name[i]);
        }
        
        cout << name[i];
    }
    
    return name;
    
}
//function to sort in ASCII style
string sort(string name)
{
    sort(name.begin(), name.end());
    
    return name;
}

Open in new window

0
Comment
Question by:joedfuse
  • 4
  • 4
8 Comments
 
LVL 30

Expert Comment

by:Zoppo
ID: 39630252
Hi joedfuse,

the first problem simply is you write the result to output twice, first char by char in the proper function itself, next in the calling function you print out the returned name.

I would suggest to remove all output in the proper function, this is a function to modify the string, not to output anything.

For the sorting you can implement your own sort comparsion function which i.e. compares the characters case independant. You can find some good info about using sort with own comparsion functions i.e. here: http://www.codeproject.com/Articles/38381/STL-Sort-Comparison-Function.

About the last: Can you post the first some errors VisualStudio generates?

Hope that helps,

ZOPPO
0
 

Author Comment

by:joedfuse
ID: 39630293
Error      1      error C3861: 'transform': identifier not found      

Error      2      error C3861: 'transform': identifier not found      

Error      3      error C3861: 'transform': identifier not found      

Error      4      error C2660: 'sort' : function does not take 2 arguments      

These are all the errors
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 39630327
ok, maybe there's a header missing which for any reason isn't needed (or available) in xcode. Try to add this line after the last include in your code:

    #include <algorithm>

Hope this helps,

ZOPPO
0
 

Author Comment

by:joedfuse
ID: 39630653
That helped get the errors away.

The link kinda just confused me some more.... there's a lot of information. What would be the steps to sort the string alphabetically?

Thanks
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 30

Expert Comment

by:Zoppo
ID: 39630792
Well, the way to go is to use the STL sort function with a predicate-functor (or maybe lambda) which implements alphabetical sorting for single characters of a string.

I'm not sure but I don't think there's a ready-to-use thing for this in STL since IMO it's not a common use case to sort the single letters of a string. So I think you need to write your own one.

Here you can see a sample which uses a functor object which implements a function to sort the characters using their lowercase values, if these are equal capital letters are placed before small letters:
	string strText1 = "The Quick Brown Fox Jumps Over The Lazy Dog";
	string strText2 = "The Quick Brown Fox Jumps Over The Lazy Dog";

	cout << "'" << strText1 << "'" << endl;

	// This is the ASCII sort as you already have
	sort( strText1.begin(), strText1.end() );

	// Here the predicate functor is implemented
	struct my_pred : public binary_function<char, char, bool>
	{
		bool operator()(const char& l, const char& r) const
		{
			char l1 = tolower( l );
			char r1 = tolower( r );

			if ( l1 == r1 )
			{
				// ensure capital letters are sorted to front
				return l < r;
			}

			return ( l1 < r1 );
		}
	};

	// this sort uses the predicate
	sort( strText2.begin(), strText2.end(), my_pred() );

	cout << "'" << strText1 << "'" << endl;
	cout << "'" << strText2 << "'" << endl;

Open in new window

The output of this code is this:
'The Quick Brown Fox Jumps Over The Lazy Dog'
'        BDFJLOQTTaceeeghhikmnoooprrsuuvwxyz'
'        aBcDeeeFghhiJkLmnOooopQrrsTTuuvwxyz'

Open in new window

Hope that helps,

ZOPPO


PS: I edited the code since there was a little error in it.
0
 

Author Comment

by:joedfuse
ID: 39637481
Thanks for the code above...

I tried to apply it and it seems to make everything lower case.

Also my proper case is still duplicating

Here is the code

//libraries to be used
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
#include <locale>
#include <algorithm>

using namespace std;
//prototypes defined
string proper(string name);
string sort(string name);

int main()
{
    //name variables being used
    string name;
    //do loop will run as long as while statement is true
    do
    {
        cout << "Please enter your name (or quit to exit): ";
        getline(cin, name);
        //changes string to uppercase
        transform(name.begin(), name.end(), name.begin(), ::toupper);
        
        if(name == "QUIT")
        {
            cout << "\nGoodbye!" << endl;
            return EXIT_SUCCESS;
        }
        
        else
        {
            //changes string to upper case
            transform(name.begin(), name.end(), name.begin(), ::toupper);
            cout << "\nYour name in upper case is: " << name << endl;
            //changes string to lower case
            transform(name.begin(), name.end(), name.begin(), ::tolower);
            //displays string in lower case
            cout << "\nYour name in lower case is: " << name << endl;
            //displays string in proper case
            cout << "\nYour name in proper case is: " << proper(name) << endl;
            //displays string in ASCII sort
            cout << "\nYour name in ASCII sort is: " << sort(name) << endl;
            
            // Here the predicate functor is implemented
            struct my_pred : public binary_function<char, char, bool>
            {
                bool operator()(const char& l, const char& r) const
                {
                    char l1 = tolower( l );
                    char r2 = tolower( r );
                    
                    if ( l1 == r2 )
                    {
                        // ensure capital letters are sorted to front
                        return l < r;
                    }
                    
                    return ( tolower( l ) < tolower( r ) );
                }
            };
            
            // this sort uses the predicate
            sort( name.begin(), name.end(), my_pred() );

            
            
            //displays string in Alpha sort
            cout << "\nYour name in Alpha sort is: " << name << '\n' << endl;
            
            
        }
        
    }
    //when name == "QUIT", the 'do' loop will stop
    while (name != "QUIT");
    //returns a successful exit
    return EXIT_SUCCESS;
}

//function to display string in proper case
string proper(string name)
{
    long l = name.length();
    name[0] = toupper(name[0]);
    
    for(int i = 1; i < l; i++)
    {
        if(name[i] != ' ')
        {
            cout << name[i];
            continue;
        }
        
        if(name[i] == ' ')
        {
            cout << ' ';
            
            i++;
            
            name[i] = toupper(name[i]);
        }
        
        cout << name[i];
    }
    
    return name;
    
}


//function to sort in ASCII style
string sort(string name)
{
    sort(name.begin(), name.end());
    
    return name;
}

Open in new window

0
 
LVL 30

Accepted Solution

by:
Zoppo earned 500 total points
ID: 39638105
Hi again,

ok, sorry, I didn't check your whole code before, I just tried to show you a way about how to sort.

BTW, it's not astounding the output is in lower case, and it has nothing to do with the new sort function, IMO this even is the case in the code you posted at first.

The problem is ou simply convert it to lower case befor :o)

You have three calls to transform (where the second one isn't needed at all since the first one already transformed it to upper case), the last one turns the string to lower case.

I would suggest to implement functions which returns lower- and upper case copies of a passed string.

You can see this in the code below which IMO works fine. I changed some more little things to avoid some errors and senseless code:

1. I changed the loop to a simpel infinite for since the do/while you had always checks a second time if name == "QUIT" in the while clause which never can be TRUE.

2. I change the proper function for several issues:
- I removed the needless second if (this is alway TRUE if the if before is FALSE) in the loop.
- I removed all output because it messes up output from main
- I added a check for an empty string in proper to avoid access violation in case of an empty string.
- I added another check to avoid an invalid access problem in case the last character in the string is a space.

//libraries to be used
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
#include <locale>
#include <algorithm>

using namespace std;
//prototypes defined
string proper(string name);
string sort(string name);
string my_tolower( string name );
string my_toupper( string name );

int main()
{
	//name variables being used
	string name, nameU;

	// endless loop, is left by return when 'quit' is entered
	for(;;)
	{
		cout << "Please enter your name (or quit to exit): ";
		getline(cin, name);

		// get string to uppercase
		nameU = my_toupper( name );

		if(nameU == "QUIT")
		{
			cout << "\nGoodbye!" << endl;
			return EXIT_SUCCESS;
		}
		else
		{
			//displays string to upper case
			cout << "\nYour name in upper case is: " << nameU << endl;
			//displays string in lower case
			cout << "\nYour name in lower case is: " << my_tolower( name ) << endl;
			//displays string in proper case
			cout << "\nYour name in proper case is: " << proper(name) << endl;
			//displays string in ASCII sort
			cout << "\nYour name in ASCII sort is: " << sort(name) << endl;

			// Here the predicate functor is implemented
			struct my_pred : public binary_function<char, char, bool>
			{
				bool operator()(const char& l, const char& r) const
				{
					char l1 = tolower( l );
					char r2 = tolower( r );

					if ( l1 == r2 )
					{
						// ensure capital letters are sorted to front
						return l < r;
					}

					return ( tolower( l ) < tolower( r ) );
				}
			};

			// this sort uses the predicate
			sort( name.begin(), name.end(), my_pred() );

			//displays string in Alpha sort
			cout << "\nYour name in Alpha sort is: " << name << '\n' << endl;
		}
	}

	//returns a successful exit
	return EXIT_SUCCESS;
}

//function to display string in proper case
string proper(string name)
{
	long l = name.length();

	// avoid errors with empty string to avoid invalid access
	if ( l == 0 )
	{
		return name;
	}

	name[0] = toupper(name[0]);

	for(int i = 1; i < l; i++)
	{
		if(name[i] != ' ')
		{
			continue;
		}

		i++;

		if ( i == l )
		{
			// stop if the space is the last character to avoid invalid access
			break;
		}

		name[i] = toupper(name[i]);
	}

	return name;
}


//function to sort in ASCII style
string sort(string name)
{
	sort(name.begin(), name.end());

	return name;
}

string my_tolower( string name )
{
	transform(name.begin(), name.end(), name.begin(), ::tolower);
	return name;
}

string my_toupper( string name )
{
	transform(name.begin(), name.end(), name.begin(), ::toupper);
	return name;
}

Open in new window

I hope this helps,

ZOPPO
0
 

Author Closing Comment

by:joedfuse
ID: 39640368
Great help.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is an explanation of a simple data model to help parse a JSON feed
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

760 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now