c++arraysstructureline-by-linefilestreams

c++ reading a a txt file line by line into a char array within an array of structures


I'm new to C++ and having a bit of trouble understanding the whole reading a file stream thing.. any help would be appreciated... here's where i'm having trouble

I Have an array of structures like this; (no I'm not allowed to use string to store these things apparently, or vectors or any other more advanced thing I haven't covered)...

struct Staff
{
    char title[TITLESIZE];
    char firstName[NAMESIZE];
    char familyName[NAMESIZE];
    char position[POSSIZE];
    char room[TITLESIZE];
    char email[POSSIZE];
};

Then I have an array of these structure;

Staff record[MAXNOSTAFF];

The data is contained in a text file separated by tabs. However some fields may contain whitespace. Data Like below:

Dr Sherine ANTOUN Lecturer 4327 3.204 sherine_antoun@gmail.com

Here is what I have written in my code...

//function prototypes
bool getRecord (ifstream& infile, Staff dataAr[], bool& fileFound);

int main()
{

    Staff record[MAXNOSTAFF];
    bool fileFound;
    ifstream infile;

    getRecord(infile, record, fileFound); //function call
    if (fileFound==true) 
    {
        cerr <<"Exiting Program"<<endl;
        exit(1);
    }

    return 0;
}

//function definitions
bool getRecord (ifstream& infile, Staff dataAr[], bool& fileFound)
{
    infile.open("phonebook.txt");

    if (infile)
    {
        fileFound = true;
        cout << "File " <<PHONEBOOK<< " opened successfully.\n\n";
    }
    else if (!infile)
    {
        fileFound =  false;
        cerr << "Error! File could not be opened. \n";
    }

    while (infile.good())
    {        

        for (int lineIndex=0; lineIndex<MAXNOSTAFF; lineIndex++)
            for (int titleIndex=0; titleIndex<TITLESIZE; titleIndex++)
            {
                cin.getline(dataAr[lineIndex].title[titleIndex], MAXNOSTAFF, '/t');
            }

    }
    //check it works properly
    for (int k=0;k<10; k++)
    {
        for (int m=0; m<11; m++)
        {
            cout << k <<". Title is : "<<dataAr[k].title[m]<<endl;
        }
    }    
    infile.close();
    return fileFound;
}

Any help would be greatly appreciated.. thank you


Solution

  • Since you can't use std::string and std::vector, sscanf() may be your choice:

        while (infile.good())
        {
            char line[BUF_SIZE];
            for (int lineIndex=0; lineIndex<MAXNOSTAFF; lineIndex++)
            {
                infile.getline(line, BUF_SIZE);
                sscanf(line, "%s %s %s %[^\t] %s %s", dataAr[lineIndex].title, dataAr[lineIndex].firstName, dataAr[lineIndex].familyName, dataAr[lineIndex].position, dataAr[lineIndex].room, dataAr[lineIndex].email);
            }
        } 
    

    Note the %[^\t] format specifier, it will match every character that's not \t(because of ^), so that the fileds that contain whitespace can be read correctly. I don't know which fields exactly contain whitespace, so I just write an example.
    EDIT:
    if std::string and std::stirngstreamis allow to use, you can split the string after get a line from the file stream:

    while (infile.good())
        {
            char line[BUF_SIZE];
            for (int lineIndex=0; lineIndex<MAXNOSTAFF; lineIndex++)
            {
                infile.getline(line, BUF_SIZE);
                stringstream ss(line);
                std::string s;
                getline(ss, s, '\t'); // get the first field
    
                getline(ss, s, '\t'); // get the second field
    
                // ...
            }
        }