Question

I am dealing with a mixed type of numbers and strings so i really have no idea how to do this except for something so simple like

ifstream fin(filename);
fin >> a;
ofstream fout(filename);
fout << b;

and here is the struct i have to deal with

struct Reservation
{
    int ID;
    char name[MAX_NAME_LENGTH];
    char phone[MAX_PHONE_LENGTH];
    int gridironID;
    char hireDate[MAX_DATE_LENGTH];
    char resDate[MAX_DATE_LENGTH];
    char startTime[MAX_TIME_LENGTH];
    char endTime[MAX_TIME_LENGTH];
    bool isPay;

    Reservation *nextReservation;
};

I really need some guidances or directions to start it , maybe with a specific kind of function or operator that i should use ?

Edit : ah yes i want the output to look like this

100001,khang,01283478233,1,1,1,1,1,1

The whole idea is to read the informations on a file from the start when you run the program , which in order to create a base resources for interacting with , after everything is done , you want to print out the informations in the base resources for the next time you start the program again.

Was it helpful?

Solution 2

For output, simply use the ostream interface (which works with cin or fstream or...)

std::ostream& operator<<(std::ostream& stream, const Reservation& reservation) {
    stream 
           << reservation.ID << "," 
           << reservation.name << "," 
           //... and so on
}

For parsing the input, if you can assume that the fields will always be separated by a single ',' (no spaces), and your strings (like name) won't contain commas or spaces, you can do:

std::istream& operator>>(std::istream& stream, Reservation& reservation) {
    stream >> reservation.ID;
    stream::char_type ignored;
    stream >> ignored; // skip over ','

    std::string aString;
    stream >> aString; // read name
    // Now copy to char array. To make sure we don't overflow it,
    // cut string to MAX_NAME_SIZE, and leave additional space for the
    // terminating '\0'.
    aString = aString.substr(0, MAX_NAME_SIZE-1);
    strcpy(reservation.name, aString.c_str());

    // and so on..
}

But this is a very basic solution. It will suffice if your input format is guaranteed to fulfill my assumptions noted above, and if you absolutely don't want to use 3rd party code. But in general, I'd advise you to find a library to read & write CSV data, or similar. It makes handling details like quoted strings, additional whitespace etc. much simpler.

And you still need to create the link relationships between your Reservations.

OTHER TIPS

Without some information regarding the actual data in the strings, it's hard to say, but basically, you'll need to define the functions:

std::ostream& operator<<( std::ostream& dest, Reservation const& source )
std::istream& operator>>( std::ostream& source, Reservation& dest );

What you put in the functions depends a bit on the data you have to deal with; your first step should be to define exactly what you want each record to look like, keeping in mind that it must be unambiguous on input. (For example, if you just use white space as a separator, you'll run into problems if any of the strings can contain white space—and names typically can.)

Outputting the targetted format is relatively simple: you output each field, with the necessary separators, etc., in the classical way. Input is more complicated, because you need to verify that the desired separators are actually present; if worst comes to worst, you may even have to read character by character, e.g. if you want to use quoted strings for the name:

std::string name;       //  Where we'll put the results;
source >> std::skipws;  //  Skip any leading white space
char ch;
if ( !source.get() || ch != '"' ) {
    source.setstate( std::ios_base::failbit );
}
while ( source.get( ch ) && ch != '"' ) {
    name += ch;
}
if ( ch != '"' ) {
    source.setstate( std::ios_base::failbit );
}

You may want to add code to handle escaped characters in the loop, or ban other characters, like '\n' in the input. This is fairly easy to do in the loop. Just remember that anytime you see anything you don't like: set std::ios_base::failbit. In addition to telling the caller that something went wrong, all of the following input will fail immediately, without extracting anything from the stream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top