CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2018
    Posts
    2

    Manipulating strings

    I have to take a name from Last, First Middle and display it as First Middle Initial and Last Name without commas. Can someone tell me where my code is wrong or better explain how to use the 'find' command to make the following code work?

    Code:
    /******************************************************************************
     * stringProg.cpp
     * 
     *
     * Program string myString and manipulation of the string.
     ******************************************************************************/
     
     #include <iostream>
     #include <string>
     
    using namespace std;
    
    void inputData(string & myString);
    void outputData(string myString);
    
    
    int main()
    {
    	string myString;
    	inputData(myString);
    	outputData(myString);
    	return 0;
    }
    
    void inputData(string & myString)
    {
    	cout << "Please type your full name in the following format:" << endl;
    	cout << "Last, First Middle  -- Note there is no comma between First and Middle" << endl;
    	string first, middle, last;
    	getline(cin, myString);
    	
    	int index = myString.find(",", 0);
    	last = myString.substr(0, index); //get last name and then erase that part
    	myString.erase(0, index + 1);     //of the string up to the index
    	
    	index = myString.find(" ", 0);
    	first = myString.substr(0, index);//get first starting with space after comma
    	myString.erase(0, index + 1);     //and erase that plus one
    	
    	index = myString.find(" ", 0);
    	middle = myString.substr(0, index);//use what is left of myString and take
    	myString.erase(0, index + 2);      //just the first character
    	
    	myString += first + " ";
    	myString += middle + " ";//myString adding each part of the name together
    	myString += last;
    	
    	myString.insert(first.length() + middle.length() + 1, " " + last.substr(0,1));
    	
    }
    
    void outputData(string myString)
    {
    	cout<< myString << endl;
    	system("pause");
    	
    
    }

  2. #2
    Join Date
    Feb 2017
    Posts
    677

    Re: Manipulating strings

    Quote Originally Posted by nmenumero1 View Post
    Can someone tell me where my code is wrong or better explain how to use the 'find' command to make the following code work?
    You're making a newbie mistake and that's to first produce a pile of code and then try to make it work. Instead use a technique called Stepwise Refinement. Enter code in small steps and make sure it works as intended after each step before you continue with the next.

    In this case first "comment out" everything in inputData after the getline statement. Then put in a print statement so you are sure myString holds what you expect.

    Then "comment in" the first manipulation of myString and make sure the result is the expected by printing it so you know for sure your code works fine so far. Then repeat this process one string manipulation at a time until you reach the wanted result.

    There's more to Stepwise Refinement than this but this is a start.
    Last edited by wolle; June 11th, 2018 at 01:41 AM.

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Manipulating strings

    ... and also learn how to use the debugger to trace through code, watch variables etc and 'see' what is happening in the code.

    Note that .find() takes as a second parameter the starting index for the search - which defaults to 0. So in your first .find(), there is no need to specify 0. Also, there is no need to erase parts from mystring - use the result of the previous find as the second parameter for the next .find() (with an appropriate adjustment) and adjust the starting position for .substr() accordingly. Also note that there is a space after the , so the search for the space separating first from middle needs to start after that. So you only need 2 finds - one to find the , and one to find the ' ' between first and middle with .substr() used to obtain the 3 parts which can then be concatenated together to produce the required string. .insert() isn't needed as the concatenation itself will produce mystring. .find() returns a type of size_t and not int. So the type of index should be size_t - or even better auto.

    Code:
    auto index = myString.find(",");
    Also note that outputdata() should take mystring as a const reference - not by value which causes an un-neccessary copy to be made.

    This assumes that there is only one space between , and first and one space between first and middle. If more than one space is allowed that additional steps will be needed to deal with that.

    For info on .find() see http://www.cplusplus.com/reference/string/string/find/

    PS As inputData() returns a string, why have it as a function parameter - why not just have it as the function return value? Modern c++ doesn't do a by-value return copy of the returned data - so there is now no performance impact.
    Last edited by 2kaud; June 11th, 2018 at 06:23 AM. Reason: PS
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    Jun 2018
    Posts
    2

    Re: Manipulating strings

    Quote Originally Posted by wolle View Post
    You're making a newbie mistake and that's to first produce a pile of code and then try to make it work. Instead use a technique called Stepwise Refinement. Enter code in small steps and make sure it works as intended after each step before you continue with the next.

    In this case first "comment out" everything in inputData after the getline statement. Then put in a print statement so you are sure myString holds what you expect.

    Then "comment in" the first manipulation of myString and make sure the result is the expected by printing it so you know for sure your code works fine so far. Then repeat this process one string manipulation at a time until you reach the wanted result.

    There's more to Stepwise Refinement than this but this is a start.
    This is sound advice. Thank you. I did finally figure out how to make my code work. Here's how it turned out.
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    void inputData(string & myString);
    void outputData(string myString);
    
    
    int main()
    {
        string myString;
        inputData(myString);
        outputData(myString);
        return 0;
    }
    
    void inputData(string & myString)
    {
        cout << "Please type your full name in the following format:" << endl;
        cout << "Last, First Middle  -- Note there is no comma between First and Middle" << endl;
        string first, middle, last;
        getline(cin, myString);    
        
        int index = myString.find(',', 0);
        last = myString.substr(0, index); //get last name and then erase that part
        myString.erase(0, index + 1);    //of the string up to the index
        
        while (myString[0]==' ') myString.erase(0, 1);    //erase left 
     
        index = myString.find(' ' , 0);
        first = myString.substr(0, index);//get first starting with space after comma
        myString.erase(0, index + 1);    //and erase that plus one
        while (myString[0]==' ') myString.erase(0, 1);    //erase left      
        
        middle=myString.substr(0, 1); //get middle initial
        myString.erase(0,myString.length());//make it empty
        myString+=first+" "+middle+" "+last;//create myString as first middle last 
       
        myString.insert(first.length()+2,".");  //insert period after middle initial
        
       //this assignment was a big headache ... glad it finally works
    }
    
    void outputData(string myString)
    {
        cout<< myString << endl;
        system("pause");
       
    
    }

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Manipulating strings

    //this assignment was a big headache ... glad it finally works
    yes great - but the code could be simplified.

    If you assume only 1 space before/after first name then consider

    Code:
    void inputData(string& myString)
    {
    	cout << "Please type your full name in the following format:" << endl;
    	cout << "Last, First Middle  -- Note there is no comma between First and Middle" << endl;
    
    	getline(cin, myString);
    
    	const auto indl = myString.find(',');
    	const auto indf = myString.find(' ', indl + 2);
    	myString =  myString.substr(indl + 2, indf - indl - 2) + " "s + myString[indf + 1] + ". "s + myString.substr(0, indl);
    }
    but if assume that there may be multiple spaces before the surname and multiple spaces before/after the first name, then consider

    Code:
    void inputData1(string& myString)
    {
    	cout << "Please type your full name in the following format:" << endl;
    	cout << "Last, First Middle  -- Note there is no comma between First and Middle" << endl;
    
    	getline(cin, myString);
    
    	const auto ind0 = myString.find_first_not_of(' ');
    	const auto indl = myString.find(',', ind0);
    	const auto ind = myString.find_first_not_of(' ', indl + 1);
    	const auto indf = myString.find(' ', ind + 1);
    	const auto ind1 = myString.find_first_not_of(' ', indf + 1);
    
    	myString = myString.substr(ind, indf - ind) + " "s + myString[ind1] + ". "s + myString.substr(ind0, indl - ind0);
    }
    Last edited by 2kaud; June 11th, 2018 at 01:18 PM. Reason: Added . after middle initial
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured