Split and Process a String in C++ into Different Variables

14,623
Roger Pont 70778745 M 20120345 [email protected]
Tommy Holness 5127438973 M 20120212 [email protected]
Lee Kin Fong 864564456434 F 30245678 [email protected]

Looking at the above data, if we process each line backward, then the problem would become quite easy:

  • Split the words on one line. Say the number of words is N.
  • The last word is email, i.e words[N-1] => email address
  • The second last is studentid, i.e words[N-2] => student id.
  • Likewise, third last is gender, fourth last is phone, and the remaining words make the name.

That gave you enough hint.

Code:

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <iterator>
#include <cassert>

struct student
{
  std::string name;
  std::string phone;
  std::string gender;
  std::string student_id;
  std::string email;
};

int main()
{
    std::vector<student> students;

    std::string line;
    while(std::getline(std::cin, line))
    {
        std::istringstream ss(line);
        std::istream_iterator<std::string> begin(ss), end;
        std::vector<std::string> words(begin, end); 

        assert(words.size() >= 5); 

        int n = words.size() - 1;
        student s { words[0], words[n-3], words[n-2], words[n-1], words[n] };
        for (int i = 1 ; i < n - 3 ; i++) s.name += " " + words[i];

        students.push_back(s);
    }

    //printing
    for(auto && s : students)
        std::cout << "name       = " << s.name  << "\n"
                  << "phone      = " << s.phone << "\n"
                  << "gender     = " << s.gender << "\n"
                  << "student_id = " << s.student_id << "\n"
                  << "email      = " << s.email << "\n\n";
}

Input:

Roger Pont 70778745 M 20120345 [email protected]
Tommy Holness 5127438973 M 20120212 [email protected]
Lee Kin Fong 864564456434 F 30245678 [email protected]

Output:

name       = Roger Pont
phone      = 70778745
gender     = M
student_id = 20120345
email      = [email protected]

name       = Tommy Holness
phone      = 5127438973
gender     = M
student_id = 20120212
email      = [email protected]

name       = Lee Kin Fong
phone      = 864564456434
gender     = F
student_id = 30245678
email      = [email protected]

Online Demo

Now spend some time to understand the code. The code I showed you is written using C++11. It demonstrates many idioms of Modern C++.

  • How to read file. Line by line.
  • How to split a line, and populate a vector of strings.
  • How to fill the struct (problem specific)

Hope that helps.

Share:
14,623
user2215892
Author by

user2215892

Updated on July 16, 2022

Comments

  • user2215892
    user2215892 almost 2 years

    I have a text file containing a bunch of data which is actually a student list.
    The structure is like: "Name" "Telephone" "Gender" "StudentID" "Email"

    Here is a sample of the list:

    Roger Pont 70778745 M 20120345 [email protected]
    Tommy Holness 5127438973 M 20120212 [email protected]
    Lee Kin Fong 864564456434 F 30245678 [email protected]

    The data is stored in a text file and I have already used the getline() function to convert each line into a string.

    That is: student[0] contains "Roger Pont 7077874567 M 20120345 [email protected]"

    My task is to sort the records according to StudentID in ascending order.

    My problem is that I wanted to split the strings into different variable types.
    However, since some names have more spaces in between and telephone number consists of different lengths, I can't use input and output streams is this way:
    stream >> name[i] >> tel[i] >> gender[i] >> StudentID[i] >> email[i];

    Any ideas how I can split the strings into different variables?

    Thanks in advance.

    Remarks: I have read this (Splitting a string into multiple variables in C++) but unlike that case, I don't have a specific pattern such as having the word "age" before the integer that represents age.