Solved

C++ string manip help!!!!

Posted on 2013-11-07
8
580 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 31

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 31

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 31

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 31

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Scripting vs. Programming languages 25 152
Path to  STL Map header file 1 43
Hide vba in gp 7 83
iSeries email authority 4 26
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now