Parsing comma delimited text in C++

I am working on a project where I am given a comma delimited string of text in an array, and need to parse each array index into its own object.

For example:

string studentData[] =
{ "Student1,Adam,Smith,ASmith@gmail.com,20", "Student2,Erick,Smith,ESmith@gmailcom,19"}

I have objects created to hold StudentName, EmailAddress, and Age, but cannot find a way to get the values from the array into the objects.
Simplest way would probably be to use a stringstream, which converts the string back into a stream (like cin or fstream), and then you can use getline on the stream to delimit it by commas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Example program
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    using namespace std;

    string studentData[] = { "Student1,Adam,Smith,ASmith@gmail.com,20", "Student2,Erick,Smith,ESmith@gmailcom,19"};
    for (int i = 0; i < 2; i++)
    {
        istringstream iss(studentData[i]);
        
        string username;
        getline(iss, username, ',');
        
        string first_name;
        getline(iss, first_name, ',');
        
        string last_name;
        getline(iss, last_name, ',');
        
        string email;
        getline(iss, email, ',');
        
        int id;
        iss >> id;
        
        string full_name = first_name + " " + last_name;
        
        std::cout << full_name << " | " << email << '\n';
    }
}

Adam Smith | ASmith@gmail.com
Erick Smith | ESmith@gmailcom
Last edited on
If the data can contain quoted text or escaped characters then parsing becomes harder because a comma could show up in either. Just something to verify.
Here is something to play with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <sstream>
#include <string>
#include <utility>

struct Student
{
  // I don't know anything about your StudentName, EmailAddress, and Age objects.
  // So I just used standard things here.
  std::string id;
  std::string first_name;
  std::string surname;
  std::string email;
  int         age;

  // Here is where we construct a student's information from a string
  Student( const std::string& s ) { from_stream( std::istringstream( s ) ); }
  Student( const char*        s ) { *this = std::string( s ); }  // be explict due to a Clang++ bug

  // Here is where we assign a student's information from a string
  Student& operator = ( const std::string& s ) { from_stream( std::istringstream( s ) ); return *this; }
  Student& operator = ( const char*        s ) { return *this = std::string( s ); }  // be explict due to a Clang++ bug

  // Here is where we extract a student's information from a stream
  std::istream& from_stream( std::istream& ins )
  {
    getline( ins, id,         ',' );
    getline( ins, first_name, ',' );
    getline( ins, surname,    ',' );
    getline( ins, email,      ',' );
    return ins >> age;
  }

  // Here is where we insert a student's information into a stream
  std::ostream& to_stream( std::ostream& outs ) const
  {
    return outs
      << id         << ","
      << first_name << ","
      << surname    << ","
      << email      << ","
      << age;
  }

  // Here are some convenient overloads for rvalue stuff that we use above
  std::istream& from_stream( std::istream&& ins  )       { return from_stream( std::forward <std::istream&> ( ins  ) ); }
  std::ostream& to_stream  ( std::ostream&& outs ) const { return to_stream  ( std::forward <std::ostream&> ( outs ) ); }
};

// Stream extraction operator for Student
std::istream& operator >> ( std::istream& ins, Student& student )
{
  return student.from_stream( ins );
}

// Stream insertion operator for Student
std::ostream& operator << ( std::ostream& outs, const Student& student )
{
  return student.to_stream( outs );
}

int main()
{
  // Here we create an array of Students -- IN SPACE! FROM STRINGS!
  Student students[] =
  {
    "Student1,Adam,Smith,ASmith@gmail.com,20",
    "Student2,Erick,Smith,ESmith@gmail.com,19",
  };

  // Prove it!
  for (const auto& student : students)
    std::cout
      << student.first_name << " "
      << student.surname    << " | "
      << student.email      << "\n";
}

I don’t normally just post code for people’s assignments like this, so beware: turning this in directly will likely raise your grader’s eyebrows.

The important parts are using standard streams to convert to and from a Student, lines 25 through 43, and the operators on lines 50 through 60. To use them, just create an istringstream and use the >> operator to parse the student information.

Good luck!

[edits] Added info
Last edited on
Topic archived. No new replies allowed.