简体   繁体   English

将逗号分隔的文本文件读入数组

[英]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. 我正在尝试用C ++编写一个程序,以模拟大学的录取系统,学生在该系统中输入其ID,然后该程序在文本文件中搜索其信息,并基于该文本文件加载结构。 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. 使用getline函数,使用','作为delim,也将延续到下一行,直到下一个逗号为止。 What would be the correct algorithm for this? 正确的算法是什么?

This is the file setup that contains fake student information: 这是包含伪造学生信息的文件设置:

  • 918273645,Steve,Albright,ITCS2530,MATH210,ENG140 918273645,史蒂夫,奥尔布赖特,ITCS2530,MATH210,ENG140
  • 123456789,Kim,Murphy,ITCS2530,MATH101 123456789,金,墨菲,ITCS2530,MATH101
  • 213456789,Dean,Bowers,ITCS2530,ENG140 213456789,Dean,Bowers,ITCS2530,ENG140
  • 219834765,Jerry,Clark,MGMT201,MATH210 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. 例如,用户输入“ 123456789”作为其ID,然后读取Kim Murphy的信息。 Upon the first iteration of getline, "ITCS2530" is read and put into the variable, and is then loaded into the struct; 在getline的第一次迭代中,将读取“ ITCS2530”并将其放入变量中,然后将其加载到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. 但是,列表中的最后一个课程在下一个逗号之前具有换行符,因此下一次迭代将读取“ MATH101 / nl213456789”,并将整个字符串放入变量中,然后尝试将其加载到结构中。

The first column is their ID, then their First name, last name, and then their currently-enrolled courses after that. 第一列是他们的ID,然后是他们的名字,姓氏,然后是他们当前正在注册的课程。 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. 问题是std :: getline恰好采用一个字符作为分隔符。 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. 答案是使用带有默认(换行符)定界符的std :: getline将整行读为字符串,然后使用字符串流来保存该行文本,因此您可以使用逗号作为定界符来调用std :: getline。

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. 我对C ++的了解很少,但是我记得这个命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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