简体   繁体   中英

Reading Comma Delimited Text File Into Array

I am trying to write a program in C++ that emulates a college enrollment system, where the student enters their ID, and the program searches a text file for their information, and loads a struct based on the text file. I have gotten to a point where I am having trouble getting their enrolled courses into the struct's array. Using the getline function, using the ',' as the delim will also carry over the next line until the next comma. What would be the correct algorithm for this?

This is the file setup that contains fake student information:

  • 918273645,Steve,Albright,ITCS2530,MATH210,ENG140
  • 123456789,Kim,Murphy,ITCS2530,MATH101
  • 213456789,Dean,Bowers,ITCS2530,ENG140
  • 219834765,Jerry,Clark,MGMT201,MATH210

(Bullets added for layout; not in the file)

For example, the user enters "123456789" for their ID, and Kim Murphy's information is then read. Upon the first iteration of getline, "ITCS2530" is read and put into the variable, and is then loaded into the struct; no problem there. However, the last course in the list has the newline character before the next comma, so the next iteration reads "MATH101/nl213456789" and puts the entire string into the variable and tries to load that into the struct.

The first column is their ID, then their First name, last name, and then their currently-enrolled courses after that. Notice that the number of enrolled courses can vary.

Here is the code that I am currently working on:

    student login()
{
    string ID;
    student newStudent;
    string enrolled;
    int i = 0;
    while (true)
    {
        cout << "Enter Student ID: ";
        cin >> newStudent.ID;
        cout << endl;
        if (newStudent.ID.length() == 9)
            break;
        else
            cout << "That ID is invalid - IDs are 9 digits" << endl;
    }
    ifstream inFile;
    ofstream outFile;
    inFile.open("registration.txt");
    if (inFile.is_open())                                                               
    //Check if file is open
    {
        while (!inFile.eof())                                                           
        //While not at end of file
        {
            getline(inFile, ID, ',');                                                   
            //Search for ID
            if (ID == newStudent.ID)
            {
                getline(inFile, newStudent.fName, ',');                                         
                //Assign fName and lName
                getline(inFile, newStudent.lName, ','); 

                while (enrolled != "\n")
                {
                    getline(inFile, enrolled, ',');
                    if (enrolled == "\n")
                    {
                        cout << "Not currently enrolled in a class." << endl;
                    }
                    else
                    {
                        newStudent.courses[i] = enrolled;
                        i++;
                    }
                }
                    cout << newStudent.lName << ", Welcome to the MCC Enrollment System!" << endl;
                for (i = 0; i <= NUM_OF_COURSES; i++)
                {
                    cout << "Enrolled courses: " << newStudent.courses[i] << endl;
                }

                    cout << endl;
                    break;
                    //Stops searching
            }
            else                                                                        
                //Ignores rest of line - used to skip to the next line
            {
                getline(inFile, ID, '\n');
            }
            if (inFile.eof())                                                           
                //If ID was not found
            {
                inFile.close();
                cout << "Enter First Name: ";                                           
                //Begin entry of new student
                cin >> newStudent.fName;
                cout << endl;
                cout << "Enter Last Name: ";
                cin >> newStudent.lName;

                cout << endl;
                outFile.open("registration.txt", ios::app);
                if (outFile.is_open())
                {
                    outFile << newStudent.ID << "," << newStudent.fName << "," << newStudent.lName << "\n";
                }
            }
        }
    }
    return newStudent;
}

Thanks in advance for any help.

The problem is that std::getline takes exactly one character as a delimiter. It defaults to a newline but if you use another character then newline is NOT a delimiter any more and so you end up with newlines in your text.

The answer is to read the entire line into a string using std::getline with the default (newline) delimiter and then use a string stream to hold that line of text so you can call std::getline with a comma as a delimiter.

Something like this:

#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>

int main()
{
    std::ifstream inFile("registration.txt");
    if (inFile.is_open())
    {
        std::string line;
        while( std::getline(inFile,line) )
        {
            std::stringstream ss(line);

            std::string ID, fname, lname;
            std::getline(ss,ID,',');    std::cout<<"\""<<ID<<"\"";
            std::getline(ss,fname,','); std::cout<<", \""<<fname<<"\"";
            std::getline(ss,lname,','); std::cout<<", \""<<lname<<"\"";

            std::vector<std::string> enrolled;
            std::string course;
            while( std::getline(ss,course,',') )
            {
                 enrolled.push_back(course); std::cout<<", \""<<course<<"\"";
            }
            std::cout<<"\n";
        }
    }
    return 0;
}

In this example I am writing the text to the screen surrounded by quotes so you can see what is read.

split(string, seperator)

split("918273645,Steve,Albright,ITCS2530,MATH210,ENG140", ",")
split("123456789,Kim,Murphy,ITCS2530,MATH101", ",")
split("213456789,Dean,Bowers,ITCS2530,ENG140", ",")
split("219834765,Jerry,Clark,MGMT201,MATH210", ",")

I know very little C++, but I remember this command.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM