-1

c++ question Hi I have a txt file seprated with comma. It is a database for school. the txt file looks like this:

AI323,12,soma gomez,Wed,department of art AM324,6,tony wang,Tue;Thu, CC+ dance school

I want my code to read the txt file and put each column in an array/vector. the result should be like:

class_code={} ; num_students={}; teacher_name={}; date={};location={}

Thnak you in advance for your hepl. Im very new to cpp.

I tried to put each of them in an array with getline command. howver, I am struggling with getting the result.

A M
  • 14,694
  • 5
  • 19
  • 44

1 Answers1

0

A very common used approach to read records from a CSV-Database is to read reading line by line from the file with std::getline. Plese read here about this function.

Then this line is again put in a stream, the std::istringstream.

With that it is possible to use again formatted or unformatted stream extraction functions, like >> or std::getline, to extract parts from the string (stingstream).

And here especially useful is the std::getline function with delimiter. You can then extract parts of a string until a certain character is found, in your case the comma (',').

Then you need to use modern C++ elements to implement a solution. Data and methods operating on this data are put in a class or struct.

And to design the reality into your program, you would need a data type (struct) "Record" and a data type (struct) "Database".

And then things will evolve.

Please see one example below. You can build your solution on this proposal:

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

// One record, so one row in the database
struct Record{
    std::string ID{};
    int no{};
    std::string name{};
    std::string day{};
    std::string department{};
    int number{};
    std::string teacher{};
    std::string days{};
    std::string location{};

    // For reading one record in SCV format from a stream with the C++ extraction operator >>
    friend std::istream& operator >> (std::istream& is, Record& r) {
        // We will read a complete line and check, if this was OK
        std::string line{}; char c;
        if (std::getline(is, line)) {

            // Now we will put this line into a std::istringstream, so that we can extract 
            // parts of it using stream functions. Basically again std::getline
            std::istringstream iss{ line };

            // and now we tryt to extract all parts of the record from the std::istringstream
            std::getline(iss, r.ID,',');
            iss >> r.no >> c;
            std::getline(iss>> std::ws, r.name, ',');
            std::getline(iss, r.day, ',');
            std::getline(iss, r.department, ',');
            iss >> r.number >> c;
            std::getline(iss >> std::ws, r.teacher, ',');
            std::getline(iss, r.days, ',');
            std::getline(iss, r.location, ',');
        }
        return is;
    }
    // For writing one record to a stream with the C++ inserter operator >> in CSV format
    friend std::ostream& operator << (std::ostream& os, const Record& r) {
        return os << r.ID << ',' << r.no << ',' << r.name << ',' << r.day << ',' << r.department << ',' <<
            r.number << ',' << r.teacher << ',' << r.days << ',' << r.location;
    }
};
struct Database {
    
    // Here we will store all records
    std::vector<Record> records{};

    // This will read a complete CSV database from a stream
    friend std::istream& operator >> (std::istream& is, Database& d) {
        // Clear/delete potential existing old data
        d.records.clear();

        // Now read complete database from stream
        for (Record r; is >> r; d.records.push_back(r))
            ;
        return is;
    }
    // And this will write all records to a stream;
    friend std::ostream& operator << (std::ostream& os, const Database& d) {
        for (const Record& r : d.records)
            os << r << '\n';
        return os;
    }
    bool load(const std::string& path) {
        // Open file and check, if it could be opened
        std::ifstream ifs(path);
        if (ifs) {
            // Read all data
            ifs >> *this;
        }
        else
            // Show error message
            std::cerr << "\n\n*** Error: Could not open file '" << path << "'\n\n";
        // return status of operation
        return not ifs.bad();
    }
    bool save(const std::string& path) {
        // Open file and check, if it could be opened
        std::ofstream ofs(path);
        if (ofs) {
            // Read all data
            ofs << *this;
        }
        else
            // Show error message
            std::cerr << "\n\n*** Error: Could not open file '" << path << "'\n\n";
        // return status of operation
        return not ofs.bad();
    }

    // Please add all functions here to work with your data in the database
    // Example: pretty print
    void display() {
        for (const Record& r : records)
            std::cout << r.ID << '\n' << r.no << '\n' << r.name << '\n' << r.day << '\n' << r.department << '\n' <<
            r.number << '\n' << r.teacher << '\n' << r.days << '\n' << r.location << '\n';
    }
};


const std::string Filename{"database.txt"};

int main() {
    Database database{};

    database.load(Filename);
    database.display();
    database.save(Filename);
}
A M
  • 14,694
  • 5
  • 19
  • 44