Hello,
so this user input all in one line string , i need to parse the input into two categories: user age and user name.
for example , the user input -->> [23:Frank] [15:Jack] [45:] [33:sofia] []
in this case i have more than one argument (delimiter, total of 3 ) which are [:] , in addition i need to get user input and stop looping once i encounter the [] at the end.
this is what i was thinking :

` string input;
vector<string> age;
vector<string> name;

cin >> input;
while (input != "[]")
{
    get age between first [ and :
    assign to age variable
    get name between : ]
    assign to user name variable

    ................

}

`
in addition - what if one of the brackets is missing a name , how can assign a blank name and skip that part in order to process the rest.
any suggestions regarding how to get and process the data.
Thank you.

You could try something like this:

// split_demo.cpp //

/*
    i need to parse the input into two categories:
    user age and user name.
    for example, the user input -->>
    [23:Frank] [15:Jack] [45:] [33:sofia] []
    in this case i have more than one argument (delimiter, total of 3 )
    which are [:],
    in addition ...
    i need to get user input and stop looping 
    once i encounter the [] at the end.
    in addition - what if one of the brackets is missing a name, 
    how can assign a blank name and ...
    skip that part in order to process the rest.
*/

#include <iostream>
#include <fstream>
#include <string>
#include <list>

const char* FNAME = "test.txt";
/*
[23:Frank] [15:Jack] [45:] [33:Sofia] []
[23:Fran] [15:Jade] [45:Joe] [33:Sommy] []
[23:Frew] [15:John] [45:Jim] [33:Suzanne] []
*/


std::list< std::string > split( const std::string& s, const std::string delimits = " \t" )
{
    std::list< std::string > tmp;
    size_t p1, p2 = 0;
    for( ; ; ) // loop forever ... until break
    {
        p1 = s.find_first_not_of( delimits, p2 ); // Note: p2 is 0 on first loop
        if( std::string::npos == p1 )
            break; // i.e. if empty or all delimits

        p2 = s.find_first_of( delimits, p1+1 );
        if( std::string::npos != p2 ) // i.e. if still more ... p2 is not past end
            tmp.push_back( s.substr( p1, p2-p1 ) );
        else
        {
            tmp.push_back( s.substr( p1 ) );
            break;
        }
    }
    return tmp;
}

bool isInt( const std::string& s )
{
    for( int len = s.size()-1 ; len >= 0; -- len )
        if( s[len] < '0' || s[len] > '9' )
            return false;
    // if reach here ...
    return true;
}




int main()
{
    std::ifstream fin( FNAME );
    if( fin )
    {
        std::list< std::string >::const_iterator it;
        std::string line;
        int count = 0;
        while( getline( fin, line ))
        {
            // step 1 ... parse line ... //
            std::list< std::string > tmp = split( line, " [:]" );

            for( it = tmp.begin(); it != tmp.end(); ++ it )
            {
                // step 2 ... see if every count == 2 is NOT an integer  //
                ++count;

                if( count == 2 )
                {
                    if( !isInt( *it ) )
                        { std::cout << *it << ";\n"; count = 0; }
                    else
                        { std::cout << "DEFAULT NAME;\n" << *it << ' '; count = 1; }
                }
                else // count == 1 //
                    std::cout << *it << ' ';
            }
            std::cout << "'End of line!'\n";
            count = 0;
        }
        fin.close();
    }
    else
        std::cout << "There was a problem opening file  "
                  << FNAME << '\n';


    std::cout << "Press 'Enter' to continue/exit ... "
              << std::flush;
    std::cin.get();
}

Or more generally ...

// split_demo.cpp //

/*
    i need to parse the input into two categories:
    user age and user name.
    for example, the user input -->>
    [23:Frank] [15:Jack] [45:] [33:sofia] []
    in this case i have more than one argument (delimiter, total of 3 )
    which are [:],
    in addition ...
    i need to get user input and stop looping
    once i encounter the [] at the end.
    in addition - what if one of the brackets is missing a name,
    how can assign a blank name and ...
    skip that part in order to process the rest.
*/

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

typedef std::vector< std::string > Container;

typedef Container::const_iterator Iter;


const char* FNAME = "test.txt";
/*
[23:Frank] [15:Jack] [45:] [33:Sofia] []
[23:Fran] [15:Jade] [45:Joe] [33:Sommy] []
[23:Frew] [15:John] [45:Jim] [33:Suzanne] []
*/



Container split( const std::string& s, const std::string delimits = " \t" )
{
    Container tmp;
    size_t p1, p2 = 0;
    for( ; ; ) // loop forever ... until break
    {
        p1 = s.find_first_not_of( delimits, p2 ); // Note: p2 is 0 on first loop
        if( std::string::npos == p1 )
            break; // i.e. if empty or all delimits

        p2 = s.find_first_of( delimits, p1+1 );
        if( std::string::npos != p2 ) // i.e. if still more ... p2 is not past end
            tmp.push_back( s.substr( p1, p2-p1 ) );
        else
        {
            tmp.push_back( s.substr( p1 ) );
            break;
        }
    }
    return tmp;
}

bool isInt( const std::string& s )
{
    for( int len = s.size()-1 ; len >= 0; -- len )
        if( s[len] < '0' || s[len] > '9' )
            return false;
    // if reach here ...
    return true;
}




int main()
{
    std::ifstream fin( FNAME );
    if( fin )
    {
        std::string line;
        while( getline( fin, line ))
        {
            // step 1 ... parse line ... //
            Container tmp = split( line, " [:]" );

            // step 2 ... see if every count == 2 is NOT an integer  //
            int count = 0;
            for( Iter it = tmp.begin(); it != tmp.end(); ++ it )
            {
                ++count;

                if( count == 2 )
                {
                    if( !isInt( *it ) )
                        { std::cout << *it << ";\n"; count = 0; }
                    else
                        { std::cout << "DEFAULT NAME;\n" << *it << ' '; count = 1; }
                }
                else // count == 1 //
                    std::cout << *it << ' ';
            }
            std::cout << "'End of line!'\n";
        }
        fin.close();
    }
    else
        std::cout << "There was a problem opening file  "
                  << FNAME << '\n';


    std::cout << "Press 'Enter' to continue/exit ... "
              << std::flush;
    std::cin.get();
}

Edited 1 Year Ago by David W

This article has been dead for over six months. Start a new discussion instead.