Panda
Panda

Reputation: 2510

Split String into parts in c++

I have just started learning c++ and I was thinking is their any way of splitting strings. Lemme make it more clear. Suppose user enters the string, date of birth in the following format dd-mm-yy. Now I wish to store the date, month and year in 3 different variables. So how do I go about ??
P.S : I googled a bit and found that this can be accomplished using the boot::regex. But still, I was wondering if there was any easier way of doing the same. Being a beginner hampers me. :P Anyways, Any help would be appreciated.
To Brief:
I want something like this.

Enter date: //Accept the date
22-3-17     //Input by user
Date : 22   //Output
Month: 3    //Output
Year : 17   //Output

Upvotes: 0

Views: 3295

Answers (4)

Francis Cugler
Francis Cugler

Reputation: 7905

Here is a full working program that has been compiled, built and successfully ran on an Intel Core 2 Quad Extreme running Windows 7 64-bit using Visual Studio 2015 Community edition that has retrieved the information the OP had asked for in a particular format, parsed the string of information or data appropriately, and displayed the results in the requested or required format.

stdafx.h

#ifndef STDAFX_H
#define STDAFX_H

#include <vector>
#include <algorithm>
#include <iterator>

#include <tchar.h>
#include <conio.h>

#include <string>
#include <iostream>
#include <iomanip>

enum ReturnCode {
    RETURN_OK = 0,
    RETURN_ERROR = 1,
}; // ReturnCode

#endif // STDAFX_H

stdafx.cpp

#include "stdafx.h"

Utility.h

#ifndef UTILITY_H
#define UTILITY_H

class Utility {
public:

    static void pressAnyKeyToQuit();

    static std::string  toUpper( const std::string& str );
    static std::string  toLower( const std::string& str );
    static std::string  trim( const std::string& str, const std::string elementsToTrim = " \t\n\r" );

    static unsigned     convertToUnsigned( const std::string& str );
    static int          convertToInt( const std::string& str );
    static float        convertToFloat( const std::string& str );

    static std::vector<std::string> splitString( const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty = true ); 

private:
    Utility(); // Private - Not A Class Object
    Utility( const Utility& c ); // Not Implemented
    Utility& operator=( const Utility& c ); // Not Implemented

    template<typename T>
    static bool stringToValue( const std::string& str, T* pValue, unsigned uNumValues );

    template<typename T>
    static T getValue( const std::string& str, std::size_t& remainder );

}; // Utility

#include "Utility.inl"

#endif // UTILITY_H

Utility.inl

// ----------------------------------------------------------------------------
// stringToValue()
template<typename T>
static bool Utility::stringToValue(const std::string& str, T* pValue, unsigned uNumValues) {
    int numCommas = std::count(str.begin(), str.end(), ',');
    if (numCommas != uNumValues - 1) {
        return false;
    }

    std::size_t remainder;
    pValue[0] = getValue<T>(str, remainder);

    if (uNumValues == 1) {
        if (str.size() != remainder) {
            return false;
        }
    }
    else {
        std::size_t offset = remainder;
        if (str.at(offset) != ',') {
            return false;
        }

        unsigned uLastIdx = uNumValues - 1;
        for (unsigned u = 1; u < uNumValues; ++u) {
            pValue[u] = getValue<T>(str.substr(++offset), remainder);
            offset += remainder;
            if ((u < uLastIdx && str.at(offset) != ',') ||
                (u == uLastIdx && offset != str.size()))
            {
                return false;
            }
        }
    }
    return true;
} // stringToValue

Utility.cpp

#include "stdafx.h"
#include "Utility.h"

// ----------------------------------------------------------------------------
// pressAnyKeyToQuit()
void Utility::pressAnyKeyToQuit() {
    std::cout << "Press any key to quit" << std::endl;
    _getch();
} // pressAnyKeyToQuit

// ----------------------------------------------------------------------------
// toUpper()
std::string Utility::toUpper(const std::string& str) {
    std::string result = str;
    std::transform(str.begin(), str.end(), result.begin(), ::toupper);
return result;
} // toUpper


// ----------------------------------------------------------------------------
// toLower()
std::string Utility::toLower(const std::string& str) {
    std::string result = str;
    std::transform(str.begin(), str.end(), result.begin(), ::tolower);
    return result;
} // toLower

// ----------------------------------------------------------------------------
// trim()
// Removes Elements To Trim From Left And Right Side Of The str
std::string Utility::trim(const std::string& str, const std::string elementsToTrim) {
    std::basic_string<char>::size_type firstIndex = str.find_first_not_of(elementsToTrim);
    if (firstIndex == std::string::npos) {
        return std::string(); // Nothing Left
    }

    std::basic_string<char>::size_type lastIndex = str.find_last_not_of(elementsToTrim);
    return str.substr(firstIndex, lastIndex - firstIndex + 1);
} // trim

// ----------------------------------------------------------------------------
// getValue()
template<>
float Utility::getValue(const std::string& str, std::size_t& remainder) {
    return std::stof(str, &remainder);
} // getValue <float>

// ----------------------------------------------------------------------------
// getValue()
template<>
int Utility::getValue(const std::string& str, std::size_t& remainder) {
    return std::stoi(str, &remainder);
} // getValue <int>

// ----------------------------------------------------------------------------
// getValue()
template<>
unsigned Utility::getValue(const std::string& str, std::size_t& remainder) {
    return std::stoul(str, &remainder);
} // getValue <unsigned>

// ----------------------------------------------------------------------------
// convertToUnsigned()
unsigned Utility::convertToUnsigned(const std::string& str) {
    unsigned u = 0;
    if (!stringToValue(str, &u, 1)) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to unsigned";
        throw strStream.str();
    }
    return u;
} // convertToUnsigned

// ----------------------------------------------------------------------------
// convertToInt()
int Utility::convertToInt(const std::string& str) {
    int i = 0;
    if (!stringToValue(str, &i, 1)) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to int";
        throw strStream.str();
    }
    return i;
} // convertToInt

// ----------------------------------------------------------------------------
// convertToFloat()
float Utility::convertToFloat(const std::string& str) {
    float f = 0;
    if (!stringToValue(str, &f, 1)) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to float";
        throw strStream.str();
    }
    return f;
} // convertToFloat

// ----------------------------------------------------------------------------
// splitString()
std::vector<std::string> Utility::splitString( const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty ) {
    std::vector<std::string> vResult;
    if ( strDelimiter.empty() ) {
        vResult.push_back( strStringToSplit );
        return vResult;
    }

    std::string::const_iterator itSubStrStart = strStringToSplit.begin(), itSubStrEnd;
    while ( true ) {
        itSubStrEnd = search( itSubStrStart, strStringToSplit.end(), strDelimiter.begin(), strDelimiter.end() );
        std::string strTemp( itSubStrStart, itSubStrEnd );
        if ( keepEmpty || !strTemp.empty() ) {
            vResult.push_back( strTemp );
        }

        if ( itSubStrEnd == strStringToSplit.end() ) {
            break;
        }

        itSubStrStart = itSubStrEnd + strDelimiter.size();
    }

    return vResult;

} // splitString

main.cpp

#include "stdafx.h"
#include "Utility.h"

int main () {
    std::string date;
    std::cout << "Enter Date in DD-MM-YY Format.\n" << std::endl;

    std::getline( std::cin, date );

    std::vector<std::string> vResults = Utility::splitString( date, "-" );

    std::cout << "\nDate : " << vResults[0] << std::endl
              << "Month: " << vResults[1] << std::endl
              << "Year : " << vResults[2] << std::endl << std::endl;    

    Utility::pressAnyKeyToQuit();   
    return 0;
} // main

Upvotes: 0

Panagiotis Sakkis
Panagiotis Sakkis

Reputation: 150

You can use the operator [] to get the characters of the string.

http://www.cplusplus.com/reference/string/string/operator[]/

Upvotes: 1

ALEXANDER KONSTANTINOV
ALEXANDER KONSTANTINOV

Reputation: 913

You can use sscanf function: http://en.cppreference.com/w/cpp/io/c/fscanf

#include <iostream>
#include <string>
using namespace std;

int main(int argc, const char * argv[]) {
    string date;
    cin>>date;
    int day, month, year;
    sscanf(date.c_str(), "%d-%d-%d", &day, &month, &year);
    cout << day << ' ' << month << ' ' << year;
    return 0;
}

Upvotes: 1

kylecorver
kylecorver

Reputation: 459

There are different methods you could do this. For the 'easiest' way I would suggest using std::string::find() methods( http://www.cplusplus.com/reference/string/string/find/) in combination with std::string::substr() method (http://www.cplusplus.com/reference/string/string/substr/)

For the use of regex you do not need boost: http://www.cplusplus.com/reference/regex/

Upvotes: 1

Related Questions