Author Topic: Class Student using STL vector ... AND ... C emulation using my Cvec ...  (Read 17933 times)

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Update:

you can contact me via this link ...

https://sites.google.com/site/andeveryeyeshallseehim/

(my/editor gmail link is on the 2nd page)



A very common student request ... demo's ...

                    1. V iew all records in memory at present
                    2. A dd a new student name and id
                    3. S ort student records
                    4. E dit/E rase a student record
                    5. L oad in student records from file
                    6. U pdate file with records currently in memory
                    7. e X it program

Code: [Select]
// Student_vector.cpp // this version 2011-07-29 //

// A simple example of processing Student records ...
// using a C++ STL vector container to hold each 'Student' object
// See MENU below to see what this program does ...

// Note:
// * this program allows only unique student id's for each record
// * this program is set to update its file, (if there were any changes),
//   before quitting

#include <iostream>
#include <iomanip> // re. setw(widthValue) stream manipulator
#include <fstream> // re. ostream, ofstream, ifstream objects
#include <sstream> // re. ostringstream object
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>  // re. tolower/toupper for case insensitive comparison

// Globals ...
using namespace std;
const char THIS_TERM[] = "fall.txt"; // file name for this term's records
const string MENU = "\n"
                    "  1. V iew all records in memory at present\n"
                    "  2. A dd a new student name and id\n"
                    "  3. S ort student records\n"
                    "  4. E dit/E rase a student record\n"
                    "  5. L oad in student records from file\n"
                    "  6. U pdate file with records currently in memory\n"
                    "  7. e X it program\n\n"
                    "Your choice (1..7) : ";

class Student
{
public:
    // Note: this name comparison is case insensitive ...
    friend bool compare_nocaseName( const Student&, const Student& );
    friend bool compare_id( const Student& a, const Student& b ) ;

    friend ostream& operator << ( ostream& os, const Student& s )
    { return os << s.name << ", " << s.id; }

    // constructors ...
    Student() {} // default ctor ...
    Student( string nam, string num ) : name( nam ), id( num ) {}

    // setters ...
    void set_name( string nam ){ name = nam; }
    void set_id( string num ) { id = num; }

    // getters ...
    string get_name() const { return name; }
    string get_id() const { return id; }
private:
    string name, // add any needed info here, just like in a C/C++ 'struct'
           id;
};


bool compare_id( const Student& a, const Student& b )
{ return a.id < b.id; }

// this name comparison (friend function) is NOT case sensitive ...
bool compare_nocaseName( const Student& a, const Student& b )
{
    size_t i = 0, lenNameA = a.name.length(), lenNameB = b.name.length();

    while( i < lenNameA && i < lenNameB
                        && tolower(a.name[i]) == tolower(b.name[i]) )
           ++i ;

    // ok ... now check end conditions ...
    if( i < lenNameA )
    {
        if( i < lenNameB ) return tolower(a.name[i]) < tolower(b.name[i]) ;
        else return false; // since i == lenNameB
    }

    // if reach here ...  i == lenNameA ... so check ...
    if( i < lenNameB ) return true; // since i == lenNameA

    // else we have  i == lenNameA   &&   i == lenNameB  ... so names equal
    return a.id < b.id;
}



// functions used by main to process a vector of Student records

int getReply( const string& msg );
void pauseForEnter();

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
vector< Student >::iterator existID( vector< Student >& term, const string& ID );

// adds Student records to end of vector of Student records ... 'term'
// gets input from keyboard ...
int newStud( vector< Student >& term );

// shows (to console screen) all student records in vector container ... 'term'
void viewStuds( const vector< Student >& term );

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const vector< Student >& term );

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( vector< Student >& term );

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( vector< Student > &term );



int main() ////////////////////////// BEGIN MAIN ///////////////////////////////
{
    // create a 'fall vector' to hold student names and ids for the 'Fall Term'
    // also holds number of records, via 'fall.size()'
    vector < Student > fall;

    // now get all records from file ... if it exists ?
    int count = readStuds( fall );
    if( count >= 0 )
        cout << count << " student record(s) read into memory ..." << endl;
    else
        cout <<"(The file will be created when some student records exist.)"
             <<endl;
    bool changes = false; // set file 'update flag' to initial value ...

    for( ;; ) // loop forever ... until break ...
    {
        int reply = getReply( MENU );
        if( reply == '1' || reply == 'V' ) // View ...
            viewStuds( fall );
        else if( reply == '2' || reply == 'A' ) // Add ... from keyboard
        {
            int numStuds = newStud( fall );
            cout << endl << numStuds << " student record(s) added ..."
                 << " The total number of student records now is "
                 << fall.size() << endl;
            if( numStuds ) // if >0 added ... update bool variable changes
                changes = true;
        }
        else if( reply == '3' || reply == 'S' ) // Sort ... but DON'T update
                                                // 'changes' unless 'data filed'
        {
            reply = getReply( "\nSort by id or name  (i/n) ? " );
            if( reply == 'I' )
            {
                // using case sensitive id's to sort ...
                sort( fall.begin(), fall.end(), compare_id) ;
                cout << "Now sorted in memory by id. ";
            }
            else if( reply == 'N' )
            {
                // using case insensitive names ...
                sort(fall.begin(), fall.end(), compare_nocaseName);
                cout << "Now sorted in memory by name. ";
            }
            else
            {
                cout << "Ok ... no new sort done here ...\n";
                continue;
            }

            reply = getReply( "Update file (y/n) ? " );
            if( reply == 'Y' )
            {
                fileStuds( fall );
                changes = false;
                cout << "File updated ...\n";
            }
            else cout << "File NOT updated ...\n";
        }
        else if( reply == '4' || reply == 'E' )
        {
            if( editStud( fall ) )
                changes = true;
        }
        else if( reply == '5' || reply == 'L' ) // Load/Read file into memory ...
        {
            int condition = readStuds( fall );
            if(  condition >= 0 )
            {
                cout << "\nThere were " << condition
                     << " student records read into memory from file." << endl;
                changes = false;
            }
        }
        else if( reply == '6' || reply == 'U' ) // Update file from memory ...
        {
            if( !changes )
                cout << "\nNo changes to file ..." << endl;
            else
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    if( fileStuds( fall ) != (int)fall.size() )
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
        }
        else if( reply == '7' || reply == 'X' ) // eXit main show MENU/loop ...
        {   // and ...
            if( changes ) // then ...
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    static int trys = 0;
                    if( fileStuds( fall ) != (int)fall.size() )
                    {
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                        ++trys;
                        if( trys < 2 ) continue;
                    }
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
            break; // and do exit program routine ...
        }
        else
        {
            cout << "\nChoice NOT implemented yet ...\n";
        } // end of if( reply == ? ) 'switch' structure ...

    } // end of main 'forever loop' ...


    // debug exit routine ...

    ifstream ftest( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !ftest )
    {
        cout << "\nError attempting to open file " << THIS_TERM << " ...\n";
        pauseForEnter();
    }
    else // if reach here ...
    {
        ftest.close(); // first close file found ok above ...
        // then ... proceed ... to open the file in a system text editor ...
        // if you have a Win OS ... show structure of file
        if( 'Y' == getReply( "Show in notepad {y/n) ? " ) )
        {
            string tmpSee = "notepad ";
            tmpSee += THIS_TERM;
            system( tmpSee.c_str() );
        }
    }

} ///////////////////////////////// END MAIN ///////////////////////////////////


int getReply( const string& msg )
{
    cout << msg << flush;
    int reply = toupper( cin.get() );
    cin.sync();
    return reply;
}
void pauseForEnter()
{
    getReply( "\nPress 'Enter' to continue ... " );
}

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
vector< Student >::iterator existID( vector< Student >& term, const string& ID )
{
    vector < Student > :: iterator it;
    for( it = term.begin(); it != term.end(); ++it )
        if( it->get_id() == ID ) return it;
    // else ...
    return it; // returns term.end() ...
}

// adds Student records to end of vector of Student records ... 'term'
// gets input from keyboard ...
int newStud( vector< Student >& term )
{
    cout << "\nEnter an empty record to exit this 'Input Loop' ..." << endl;
    int count = 0;
    string nam, num;
    for( ;; ) // loop forever until break ...
    {
        cout << "\nID   : ";
        getline( cin, num );
        if( existID( term, num ) != term.end() )
        {
            cout << "\nThat 'id' " << num << " already exits ... " << endl;
            continue; // from the top of the forever loop right now
        }
        cout << "Name : ";
        getline( cin, nam );
        if( nam == "" || num == "")
            break;

        int reply = getReply( "Add or Redo (a/r) ? " );
        if( reply != 'A' )
        {
            cout << "Aborted ..." << endl;
            continue;
        }

        // ok ... create and add this record to the end of the vector ...
        term.push_back( Student( nam, num ));
        ++count;
        cout << "Added " << count << " ..." << endl;
    }
    return count; // i.e. the count of added new students ...
}

// shows (to console screen) all student records in vector container ... 'term'
void viewStuds( const vector< Student >& term )
{
    vector < Student > :: const_iterator it;
    int i = 0;
    cout << endl; // leading blank line ...
    for( it = term.begin(); it != term.end(); ++it )
    {
        ostringstream oss;
        oss << "vector(" << setw(3) << setfill('0') << ++i << "):  " << *it;
        cout << left << setw(39) /*<< setfill(' ')*/ << oss.str();
        if( i % 2 == 0 ) cout << endl; // print 2 per line ...
    }
    if( i % 2 == 1 ) cout << endl; // if only a half line ... go to a new line
}

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const vector< Student >& term )
{
    ofstream fout( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !fout )
    {
        cout << "\nError attempting to open file " << THIS_TERM << endl;
        return -1;    // report error condition ...
    }

    // else ...
    vector < Student > :: const_iterator it;
    int i = 0;
    for( it = term.begin(); it != term.end(); ++it, ++i )
        fout << it->get_name() << "," << it->get_id() << endl;

    fout.close();

    if( i == (int)term.size() )
        cout << "\nAll " << i << " records filed ok." << endl;
    else
        cout << "\nOnly " << i << " of " << term.size()
             << " records were written ..." << endl;

    return i; // report success ... i.e. report count of records filed
}

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( vector< Student >& term )
{
    ifstream fin( THIS_TERM ); // recall THIS_TERM is a Global variable
    if ( !fin )
    {
        cout << "Error attempting to open file " << THIS_TERM
             << " ... Perhaps it dosen't exist yet?" << endl;
        return -1;          // report error condition ...
    }

    // else ... check existing term.size() first before re-setting?
    if( term.size() ) // i.e. if not == 0 ...
    {
        cout << "\nDo you want over-write the " << term.size();
        int reply = getReply( " records in memory (y/n) ? " );
        if( reply != 'Y' )
        {
            cout << "Aborted ... " << flush;
            return 0;
        }
        // if reach here ...
        cout << "Ok ... will over-write the " << term.size()
             << " records in memory ... " << flush;
    }

    // if reach here ...
    term.clear(); // set to empty vector
    string nam, num;
    int i;
    for( i = 0; getline( fin, nam, ',' ); ++i ) // get 1st string (up to ',')
    {
        getline( fin, num, '\n' ); // then get rest of line (up to '\n')
        term.push_back( Student(nam, num) ); // construct and add new Student
    }
    fin.close();
    return i; // report success? ... i.e. return the record count ...
}

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( vector< Student > &term )
{
    cout << "\nNote: just enter an empty record to exit this 'Edit/Erase Function'"
         << "\nOk ... now enter the ID of the student record to edit : "
         << flush;
    string idStr, nam;
    getline( cin, idStr );

    vector< Student >::iterator i, index;
    i =  existID( term, idStr );
    if( i == term.end() )
    {
        cout << "This '" << idStr << "' does not exist." << endl;
        return false;
    }

    // else ... show ... and ask if ok to edit ...
    cout << "Name : " << i->get_name() << endl
         << "ID   : " << i->get_id() << endl;

    int reply = getReply( "Abort or Edit/Erase (a/e) ? " );
    if( reply != 'E' )
    {
        cout << "Aborted ... " << endl;
        return false;
    }

    reply = getReply( "\nDo you want to erase this record (y/n) ? " );
    if( reply == 'Y' )
    {
        term.erase( i );
        cout << "Erased ...\n";
        return true;
    }


    // else ... ok ... so will edit id ... then name

    cout << "\nOk ... will edit ... Recall ...\n"
         << "Just enter an 'empty string' to abort/exit this edit ... "
         << "\nEnter NEW ID   : ";
    getline( cin, idStr );
    index = existID( term, idStr );
    if( index != term.end() && index != i ) // exclude 'i' so can edit 'i'
    {
        cout << "\nThe ID '" << idStr << "' already exits ... " << endl;
        return false; // exit to menu now ...
    }

    // ok ... get new name ...

    cout << "Enter NEW Name : ";
    getline( cin, nam );
    if( nam == "" || idStr == "" )
    {
        cout << "Aborted ..." << endl;
        return false;
    }

    reply = getReply( "Ok or Redo (o/r) ? " );
    if( reply != 'O' ) // cap 'O' ... as in Ok
    {
        cout << "Aborted ..." << endl;
        return false;
    }

    // ok ... so ... go ahead and edit
    i->set_name( nam );
    i->set_id( idStr );
    cout << "Edited ..." << endl;
    return true;
}
« Last Edit: June 23, 2015, 07:14:17 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: Class Student using STL vector ...
« Reply #1 on: July 29, 2011, 04:32:52 AM »
 An example of a data file used/produced by the above program ...

// file name :  fall.txt

Code: [Select]
Bob Jones,1
Suzy McQueen,2
Tim Horton,3
Bob Jones,4
Suzy McQueen,5
Jane Thomas,10
Jane Thomas,6

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Ok ... here is the C emulation using my readWord.h, Cvec.h, Cvec_func's.h ...

Code: [Select]
/* Student_Cvec.c // this version 2011-07-29 // */

/*
   A simple example of processing Student records ...
   using my Cvec  ... an emulation of the C++ STL vector container ...
   to hold each 'Student' object/record/Cvec_member

   See MENU below to see what this program does ...

   Note:
   * this program allows only unique student id's for each record
   * this program is set to update its file, (if there were any changes),
     before quitting
*/

#include "readWord.h" /* includes stdio.h, stdlib.h, string.h, etc... */
#include <ctype.h>   /* re. tolower/toupper for case insensitive comparison */

/* Globals ... */
#define THIS_TERM "fall.txt" /* file name for this term's records */

#define MENU "\n" \
             "  1. V iew all records in memory at present\n" \
             "  2. A dd a new student name and id\n" \
             "  3. S ort student records\n" \
             "  4. E dit/E rase a student record\n" \
             "  5. L oad in student records from file\n" \
             "  6. U pdate file with records currently in memory\n" \
             "  7. e X it program\n\n" \
             "Your choice (1..7) : "

typedef struct myStudent
{
    char* name;
    char* id;
} Student ;

#define Rec Student

void freeVrec( Rec* p )
{
    free( p->id );
    free( p->name );
}

/* Ok ... now can ... */
#include "Cvec.h"
/* ... and then can ... */
#include "Cvec_func's.h"

/* Note: this name comparison is NOT case sensitive ... */
int compare_nocaseName( const Rec* x, const Rec* y )
{
    char *a = x->name, *b = y->name;
    int test;
   
    while( *a  &&  *b  &&  tolower(*a) == tolower(*b) )  ++a, ++b ;
    /* ok ... now check end conditions ... */
   
    test = tolower(*a) - tolower(*b) ;
    if( test ) return test;
   
    /* else ... names equal since test == 0 above ... so ... */
    return strcmp(x->id, y->id);
}

int compare_id( const Rec* a, const Rec* b )
{
    return strcmp(a->id, b->id );
}


/* functions used by main to process a vec of Student records */

int getReply( const char msg[] );
void pauseForEnter();
int existID( Cvec* term, const char* ID );
int newStud( Cvec* term );
void viewStuds( const Cvec* term );
int fileStuds( const Cvec* term );
int readStuds( Cvec* term );
int editStud( Cvec* term );


int main() /* //////////////////////// BEGIN MAIN /////////////////////////// */
{
    FILE* ftest;
    int count, changes = 0; /* set file 'changes' flag to initial value */
   
    /* create a 'fall vec' to hold student names and ids for the 'Fall Term'
       also holds number of records, via 'fall.size' */
    Cvec fall;
    initCvec( &fall );

    /* now get all records from file ... if it exists ? */
    count = readStuds( &fall );
    if( count >= 0 )
        printf( "%d student record(s) read into memory ...\n", count );
    else
        puts( "(The file will be created when some student records exist.)" );

    for( ;; ) /* loop forever ... until break ... */
    {
        int reply = getReply( MENU );
       
        if( reply == '1' || reply == 'V' ) /* View ... */
            viewStuds( &fall );
        else if( reply == '2' || reply == 'A' ) /* Add ... from keyboard */
        {
            int numNewStuds = newStud( &fall );
            printf( "\n%d student record(s) added ...  "
                    "The total number of student records now is %d\n",
                    numNewStuds, fall.size );
            if( numNewStuds ) /* if >0 added ... update bool variable changes */
                changes = 1;
        }
        else if( reply == '3' || reply == 'S' ) /* Sort ... but DON'T update
                                                'changes' unless 'data filed' */
        {
            reply = getReply( "\nSort by id or name  (i/n) ? " );
            if( reply == 'I' )
            {
                msortCvec( &fall, compare_id ); /* case sensitive id's in sort */
                fputs( "Now sorted in memory by id. ", stdout );
            }
            else if( reply == 'N' )
            {
                msortCvec( &fall, compare_nocaseName ); /* case insensitive */
                fputs( "Now sorted in memory by name. ", stdout );
            }
            else
            {
                puts( "Ok ... no new sort done here ..." );
                continue;
            }

            reply = getReply( "Update file (y/n) ? " );
            if( reply == 'Y' )
            {
                fileStuds( &fall );
                changes = 0; /* reset so will match present file ... */
                puts( "File updated ..." );
            }
            else puts( "File NOT updated ..." );
        }
        else if( reply == '4' || reply == 'E' )
        {
            if( editStud( &fall ) )  changes = 1;
        }
        else if( reply == '5' || reply == 'L' ) /* Load/Read file into memory */
        {
            int condition = readStuds( &fall );
            if(  condition >= 0 )
            {
                printf( "\nThere were %d student records read into memory "
                        "from file.\n", condition );
                changes = 0; /* reset so will match present file ... */
            }
        }
        else if( reply == '6' || reply == 'U' ) /* Update file from memory */
        {
            if( !changes )
                puts( "\nNo changes to file ..." );
            else
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    if( fileStuds(&fall) != fall.size )
                        puts( "\nUNEXPECTED ERROR! NOT all records were filed!"
                              "\nTry again ... If Error persits call IT." );
                    else
                    {
                        changes = 0; /* update file flag */
                        puts( "File write operation confirmed." );
                    }
                }
            }
        }
        else if( reply == '7' || reply == 'X' ) /* eXit main show MENU/loop */
        {   /* and ... */
            if( changes ) /* then ... */
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    static int trys = 0;
                    if( fileStuds( &fall ) != fall.size )
                    {
                        puts( "\nUNEXPECTED ERROR! NOT all records were filed!"
                              "\nTry again ... If Error persits call IT." );
                        ++trys;
                        if( trys < 2 ) continue;
                    }
                    else
                    {
                        changes = 0; /* update file flag */
                        puts( "File write operation confirmed." );
                    }
                }
            }
            break; /* and do exit program routine ... */
        }
        else
        {
            puts( "\nChoice NOT implemented yet ..." );
        } /* end of if( reply == ? ) 'switch' structure ... */

    } /* end of main 'forever loop' ... */


    /* debug exit routine ... */

    ftest = fopen(THIS_TERM, "r"); /* recall 'THIS_TERM' is a Global variable */
    if( !ftest )
    {
        printf( "\nError attempting to open file %s ...", THIS_TERM );
        pauseForEnter();
    }
    else /* if reach here ... */
    {
        fclose( ftest ); // first close file found ok above ...
        /* then ... proceed ... to open the file in a system text editor ...
           if you have a Win OS ... show structure of file */
        if( 'Y' == getReply("Show in notepad (y/n) ? ") )
            system( "notepad " THIS_TERM ); /* compiler concat's strings */
    }
   
    return 0;

} /* /////////////////////////////// END MAIN /////////////////////////////// */


int getReply( const char msg[] )
{
    int c, reply;
    fputs( msg, stdout ); fflush( stdout );
    c = reply = toupper( getchar() );
    while( c != '\n' ) c = getchar(); /* flush stdin ... */
    return reply;
}
void pauseForEnter()
{
    getReply( "\nPress 'Enter' to continue ... " );
}

/* returns a valid iterator if ID is used already ... otherwise returns 'end()' */
int existID( Cvec* term, const char* ID )
{
    int i;
    for( i = 0; i < term->size; ++i )
        if( strcmp(term->ary[i].id, ID) == 0 ) return i;
    /* else ... */
    return -1;
}

/* adds Student records to end of vec of Student records ... 'term'
   gets input from keyboard ... */
int newStud( Cvec* term )
{
    int count = 0;
    Rec rec;
   
    puts( "\nNote: Enter quit to exit this 'Input Loop' ..." );
    for( ;; ) /* loop forever until break ... */
    {
        char c;
        fputs( "\nID   : ", stdout ); fflush( stdout );
        rec.id = readWord( stdin, 8, "\n", &c );
        if( strcmp(rec.id, "quit") == 0 ) { free(rec.id); return 0; }
       
        if( existID( term, rec.id ) != -1 )
        {
            printf( "\nThat 'id' %s already exits ...\n", rec.id );
            free( rec.id );
            continue; /* from the top of the forever loop right now */
        }
       
        fputs( "Name : ", stdout ); fflush( stdout );
        rec.name = readWord( stdin, 32, "\n", &c );
       
        if( getReply( "Add or Redo (a/r) ? " ) != 'A' )
        {
            puts( "Aborted ..." );
            freeVrec( &rec );
            continue;
        }

        /* ok ... create and add this record to the end of the vec ... */
        push_backCvec( term, &rec );
        ++count;
        printf( "Added %d ...\n", count );
    }
    return count; /* i.e. the count of added new students ... */
}

// shows (to console screen) all student records in vec container ... 'term'
void viewStuds( const Cvec* term )
{
    Rec* it;
    int i;
    char buf[256];
    putchar( '\n' ); /* leading blank line ... */
    for( i = 0 ; i < term->size ;  )
    {
        it = &term->ary[i];
        sprintf( buf, "(%03d): %s, %s", ++i, it->name, it->id );
        printf( "%-30s", buf );
        if( i % 2 == 0 ) putchar( '\n' ); /* print 2 per line ... */
    }
    if( i % 2 == 1 ) putchar( '\n' ); /* if only a half line, go to a new line */
    fflush( stdout );
}

/* file all records in memory ... create/overwrite file with name 'THIS_TERM' */
int fileStuds( const Cvec* term )
{
    FILE* fout = fopen( THIS_TERM, "w" ); /* recall 'THIS_TERM' is a Global variable */
    if( !fout )
    {
        printf( "\nError attempting to open file %s\n", THIS_TERM );
        return -1;    /* report error condition ... */
    }
    else
    {
        Rec* it;
        int i;
        for( i = 0; it != NULL; ++i )
        {
            it = &term->ary[i];
            fprintf( fout, "%s, %s\n", it->name, it->id );
        }
        fclose( fout );

        if( i == term->size )
            printf( "\nAll %d records filed ok.\n", i );
        else
            printf( "\nOnly %d of %d records were written ...\n", i, term->size );

        return i; /* report success ... i.e. report count of records filed */
    }
}

/* reads in all Student records from file 'THIS_TERM' ... if it exists
   returns -1 if no file exists; else returns the number of records read */
int readStuds( Cvec* term )
{
    int i;
    char c;
    Rec rec;
    FILE* fin = fopen( THIS_TERM, "r" ); /* recall THIS_TERM is a Global variable */
    if( !fin )
    {
        printf( "Error attempting to open file %s"
                " ... Perhaps it dosen't exist yet?\n\n", THIS_TERM );
        return -1; /* report error condition ... */
    }

    /* else ... check existing term size first before re-setting? */
    if( term->size ) /* i.e. if not == 0 ... */
    {
        printf( "\nDo you want over-write the %d", term->size );
        if( getReply(" records in memory (y/n) ? ") != 'Y' )
        {
            fputs( "Aborted ... ", stdout ); fflush( stdout );;
            return 0;
        }
        /* if reach here ... */
        printf( "Ok ... will over-write the %d records in memory ... ",
                term->size );  fflush( stdout );
    }

    /* if reach here ... */
    clearCvec( term ); /* set to empty vec */
    for( i = 0; (rec.name = readWord( fin, 32, ",", &c )); ++i ) /* get 1st string (up to ',') */
    {
        rec.id = readWord(fin, 8, "\n", &c); /* then get rest of line (up to '\n') */
        push_backCvec( term, &rec );
    }
    fclose( fin );
    return i; // report success? ... i.e. return the record count ...
}

/* returns 1 if a record was edited or erased ... otherwise returns 0 */
int editStud( Cvec* term )
{
    int i, index;
    char *idStr, *nam;;
    char c;
   
    fputs( "\nNote: just enter quit to exit this 'Edit/Erase Function'"
           "\nOk ... now enter the ID of the student record to edit/erase : ",
           stdout ); fflush( stdout );

    idStr = readWord( stdin, 8, "\n", &c );
    if( strcmp(idStr, "quit") == 0 ) { free(idStr); return 0; }

    i =  existID( term, idStr );
    if( i == -1 )
    {
        printf( "This '%s' does not exist.\n", idStr );
        free( idStr );
        return 0;
    }

    /* else ... show ... and ask if ok to edit ... */
    printf( "Name : %s\n"
            "ID   : %s\n", term->ary[i].name, term->ary[i].id );

    if( getReply("Abort or Edit/Erase (a/e) ? ") != 'E' )
    {
        puts( "Aborted ... " );
        free( idStr );
        return 0;
    }

    if( getReply("\nDo you want to erase this record (y/n) ? ") == 'Y' )
    {
        eraseCvec( term, i );
        puts( "Erased ..." );
        free( idStr );
        return 1;
    }


    /* else ... ok ... so will edit id ... then name */

    fputs( "\nOk ... will edit ... Recall ... "
           "just enter quit to abort/exit this edit."
           "\nEnter NEW ID   : ", stdout ); fflush( stdout );
    free( idStr );
    /* now get new id string ... */
    idStr = readWord( stdin, 8, "\n", &c );
    if( strcmp(idStr, "quit") == 0 ) { free(idStr); return 0; }
   
    index = existID( term, idStr );
    if( index > -1 && index != i ) /* exclude 'i' so can edit 'i' */
    {
        printf( "\nThe ID '%s' already exits ...\n", idStr );
        free( idStr );
        return 0; /* exit to menu now ... */
    }

    /* ok ... get new name ... */

    fputs( "Enter NEW Name : ", stdout ); fflush( stdout );
    nam = readWord( stdin, 32, "\n", &c );
    if( nam[0] == 0 || idStr[0] == 0 )
    {
        puts( "Aborted ..." );
        free( nam ); free( idStr );
        return 0;
    }

    if( getReply("Ok or Redo (o/r) ? ") != 'O' ) /* cap 'O' ... as in Ok */
    {
        puts( "Aborted ..." );
        free( nam ); free( idStr );
        return 0;
    }

    /* ok ... so ... go ahead and edit, but first ... */
    freeVrec( &term->ary[i] );
   
    term->ary[i].name = nam;
    term->ary[i].id = idStr;
    puts( "Edited ..." );
    return 1;
}

Here is a link to the included files used by the above C emulation ...

http://developers-heaven.net/forum/index.php/topic,2580.0.html
« Last Edit: July 30, 2011, 04:29:43 AM by David »