Instruction: You must use pointers for this lab. No arrays, no structures. For example, if you
need an array of floats to hold the scores, do not use float score[15]. Rather use float score,
then use dynamic memory allocation to hold required memory. You must use memory
optimally, that is if you have only 6 scores, you must point to a memory chunk of
sizeof(float)
6 bytes.
Similarly, to hold a name, instead of doing it with 2D char arrays, use 2D pointers (char
firstName[15][20] → char **firstName).
Problem:
Write a menu based program to maintain student records. Your program should take the following
inputs:
1. Student first name (max. 20 characters)
2. Student last name, (max. 20 characters)
3. Student scores (float/double), eg. 85.4
Your program should be able to take records of a minimum of 5 students. After taking the records,
you should provide 8 functionalities to the user.
1. Print records – prints records of all students
2. Add a new record – take a new record from the user for a new student. Be careful, you may need
to allocate more memory using dynamic memory allocation.
3. Delete record(s) – to delete a record, ask for the last name of the student from the user. If there
are multiple students with same last name, you must delete all of their records. You must free up the
memory holding these records.
4. Search by last name – prints record of the student with a given last name. If there are multiple
students with the same last name, print records for all of them.
5. Sort by score – sort the records of students according to their scores, and then print the sorted
records.
6. Sort by last name – sort the records of students according to their names alphabetically, and then
print the sorted records.
7. Find the median score – compute the median score and print it. Also, print how many students are
above this median score.
8. Exit the program – terminate on a specific input from the user. Let that specific input be an
integer of value 0.
You should print the record in the following format:
First Name: firstname 1, Last Name: lastname 1, Score: score 1
First Name: firstname 2, Last Name: lastname 2, Score: score 2
.
.
.
You should write each functionality from 1-7 in separate functions. You should provide a menu to
the user as following:
For inputs:
Please indicate number of records you want to enter (min 5):

of records

After user gives the number of records, you should inform the user how to enter the records:
Please input records of students (enter a new line after each record), with following format
first name last name score
After user gives the inputs for the records, inform the user about the functionalities:
Print records (press 1)
Add a new record (press 2)
Delete record(s) (press 3)
Search by last name (press 4)
Sort by score (press 5)
Sort by last name (press 6)
Find median score (press 7)
Exit the program (press 0)
After user chooses a functionality, your program performs that and provides this menu again to
select another functionality. This goes on until user presses 0.

Recommended Answers

All 5 Replies

We don't do homework. Show us first what you have even if it's faulty, that doesn't matter. Then we will help.

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

int main()

{

       char **fname;

       char **lname;

       char *name;

       float *score;

       printf("wlecom to Student Records Maintance System\n");

       printf("Number of records you want to enter(min-3):");

                     scanf("%d", &noRecords);

                     fname=(char**)malloc(10*sizeof(*fname));

                     lname=(char**)malloc(10*sizeof(*lname));

                     score = (float*)malloc(10*sizeof(float));

                     for(int i=0;i<noRecords;i++)

                     {

                     printf("Enter score of %d student:",i+1);

                     scanf("%f",&score[i]);

                     fname[i]=(char*)malloc(20+1);

                     printf("Enter fname of %d student:",i+1);

                     scanf("%s",fname[i]);

                     lname[i]=(char*)malloc(20+1);

                     printf("Enter lname of %d student:",i+1);

                     scanf("%s",lname[i]);

                     }

       do

       {

       printf("\n*Print records(Press 1)\n");

       printf("*Add new records(Press 2)\n");

       printf("*Delete record(s)(Press 3)\n");

       printf("*Search by last name(Press 4)\n");

       printf("*Search by score(Press 5)\n");

       printf("*Sort by last name(Press 6)\n");

       printf("*Find median score(Press 7)\n");

       printf("*Exit the program Print(Press 0)\n");

       printf("*Enter Your choice:");

       scanf("%d",&choice);

       switch(choice)

       {

       case 1:for(int i=0;i<noRecords;i++)

                     {

                           printf("\nFirst name: %s Last name: %s Score: %f \n",*(fname+i),*(lname+i),*(score+i));

                     }

                 break;

       case 2:

                     printf("Enter score of the student %d:",noRecords);

                     scanf("%f",&score[noRecords]);

                     fname[noRecords]=(char*)malloc(20+1);

                     printf("Enter fname the student %d:",noRecords);

                     scanf("%s",fname+noRecords);

                     lname[noRecords]=(char*)malloc(20+1);

                     printf("Enter lname of the student %d:",noRecords);

                     scanf("%s",lname+noRecords);

                           noRecords++;

                     break;

       case 3:       printf("Enter the last name of the student:");

                     name=(char*)malloc(20+1);

                     scanf("%s",name);

                     for(int i=0;i<noRecords;i++)

                     {

                           if(name==lname[i])

                           {

                                  free(lname[i]);

                                  free(fname[i]);

                                  free(score[i]);

                           }

                     }

                     break;

       case 0:printf("exiting..");exit(0); break;

       default: printf("\nInvalid choice\n");

       }

       }while(1);



       }

Where in your code is the problem? Please specify.

This 'question' may be a little 'stale' by now,

but an edit/fix of the OP's code,

may serve as a demo for other C students

who stop in at Dani's fav student place,

The following C code is an example of how pointer arithmetic

could be used exclusively in a C program (as per the original spec's.)

Enjoy :)

P.S.

The use of parallel (arrays) blocks of (contigious) memory is 'old school'
and code for a soulution to this problem
would be much clearer/simpler
if a C struct (data record) was used instead (of parallel arrays)

And ... using a Cvec of struct would further simplify the code ...
and make the logic flow clearer ...
and thus ... much easier to code/maintain.

Re. file "Cvec.h" ...
see:
http://developers-heaven.net/forum/index.php/topic,2580.msg2862.html#msg2862

/* pointers_only.c */  /* 2015-08-02 */


/*
    A demo of using exclusively C pointer arithmetic
    for all blocks of memory ...
    and all items stored in those blocks memory.

    Note: this 'solution' uses the custom C utility file:
    readLine.h
    Please see comment and link below to freely obtain a copy.
*/

#include <math.h>

#include "readLine.h"
/*
    NOTE! the include file readLine.h ... IS freely available at:
    http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864
*/



#define EPISILON pow( 10.0, -6 )

#define MEMERR "There was a problem allocating memory."


/* 2 handy utilities for many C student coding problems ... */
int takeInChr( const char* msg )
{
    char chr;
    printf( msg ); fflush( stdout );
    chr = getchar();
    if( chr != '\n' ) while( getchar() != '\n' ) ; /* flush stdin ... */
    return chr;
}
int more() /* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered */
{
    int c = takeInChr( "More (y/n) ? " );
    if( c == 'n' || c == 'N' ) return 0;
    /* else ... */
    return 1;
}

/* a simple student way to handle numeric input ...
   so program won't crash on bad input */
int takeInInt( const char* msg, int myMin, int myMax )
{
    int good = 0, val = 0;
    while( !good )
    {
        printf( msg ); fflush( stdout );

        if( scanf( "%d", &val ) == 1 && getchar() == '\n' ) good = 1;
        else
        {
            printf( "\nInteger input only here please ...\n" );
            while( getchar() != '\n' ) ; /* flush stdin ... */
        }

        if( good && ( val < myMin || val > myMax ) )
        {
            good = 0;
            printf( "\nValid input only in range %d..%d\n", myMin, myMax );
        }
    }
    return val;
}

/* a simple student way to handle numeric input ...
   so program won't crash on bad input */
float takeInFlt( const char* msg, float myMin, float myMax )
{
    int good = 0;
    float val = 0;
    while( !good )
    {
        printf( msg ); fflush( stdout );

        if( scanf( "%f", &val ) == 1 && getchar() == '\n' ) good = 1;
        else
        {
            printf( "\nNumbers only here please ...\n" );
            while( getchar() != '\n' ) ; /* flush stdin ... */
        }

        if( good && ( val < myMin || val > myMax ) )
        {
            good = 0;
            printf( "\nValid input only in range %.1f..%.1f\n", myMin, myMax );
        }
    }
    return val;
}

/* using readLine and getting new dynamic memory  ... so can return address */
char* takeInStrMaxLen( const char* msg, unsigned maxLen )
{
    char* p = NULL;

    for( ; ; )
    {
        fputs( msg, stdout ); fflush( stdout );

        p = readLine( stdin );

        if( p[0] && strlen( p ) <= maxLen )
            break;

        else if( !p[0] ) printf( "\nBlank line NOT valid input here ... \n" );
        else printf( "\nFor '%s', max len of %u char's was exceeded ... \n",
                     p, maxLen );

        free( p ); /* try again ... */
    }

    return p;
}

void showRec( const char* n1, const char* n2, const float sc )
{
    printf( "First name: %-20s Last name: %-20s Score: %5.1f \n", n1, n2, sc );
}

void takeInRec( char** n1, char** n2, float* sc, int i )
{
    char* buf = newMem( 132 );

    sprintf( buf, "\nEnter fname of student %d: ", i+1 );
    *n1 = takeInStrMaxLen( buf, 20 );

    sprintf( buf, "Enter lname of student %d: ", i+1 );
    *n2 = takeInStrMaxLen( buf, 20 );

    sprintf( buf, "Enter score for student %d: ", i+1 );
    *sc = takeInFlt( buf, 0, 100 );

    free( buf );
}

int showMenuGetChoice()
{
    putchar( '\n' );
    printf( "<1> Print records\n" );
    printf( "<2> Add new records\n" );
    printf( "<3> Delete all records with a specified last name\n" );
    printf( "<4> Find all records with a specified last name\n" );
    printf( "<5> Sort by score\n" );
    printf( "<6> Sort by last name\n" );
    printf( "<7> Find median score\n" );
    printf( "<0> Exit the program\n" );
    return takeInInt( "Pleasee enter choice in range 0..7 : ", 0, 7 );
}

int findLastName( char** lname, int size, const char* name )
{
    int i = size-1;
    for(  ; i >= 0; -- i )
    {
        if( strcmp( *(lname+i), name ) == 0 ) return i;
    }
    /* if reach ehre ... */
    return -1;
}
/*
int findFirstLast( char** fname, char** lname, int size, const char* fn, const char* ln )
{
    int i = 0;
    for(  ; i < size; ++ i )
    {
        if( strcmp(*(lname+i), ln) == 0 && strcmp(*(fname+i), fn) == 0 ) return i;
    }
    // if reach ehre ... //
    return -1;
}
*/
int findScore( const float* scores, int size, float score )
{
    int i = 0;
    for(  ; i < size; ++ i )
    {
        if( fabs( *(scores+i) - score) < EPISILON ) return i;
    }
    /* if reach here ... */
    return -1;
}

int deleteIndex( char** fns, char** lns, float* scs, int size, int j )
{
    if( size > 0 && j < size )
    {
        /* copy above down and over ... */
        free( *(lns+j) );
        free( *(fns+j) );
        for( ; j < size-1; ++ j )
        {
            *(scs+j) = *(scs+j+1);
            *(lns+j) = *(lns+j+1);
            *(fns+j) = *(fns+j+1);
        }
        return size-1;
    }

    return 0;
}

/* sort by last names */
void bubSortLastName( char** fns, char** lns, float* scs, int size )
{
    int aswap;
    do
    {
        int i = 1;
        aswap = 0;
        for( ; i < size; ++ i  )
        {
            if( strcmp( *(lns+i), *(lns+i-1) ) < 0 ) /* swap */
            {
                float tmpFlt;
                char* tmp = *(lns+i);
                *(lns+i) = *(lns+i-1);
                *(lns+i-1) = tmp;

                tmp = *(fns+i);
                *(fns+i) = *(fns+i-1);
                *(fns+i-1) = tmp;

                tmpFlt = *(scs+i);
                *(scs+i) = *(scs+i-1);
                *(scs+i-1) = tmpFlt;

                aswap = 1;
            }
        }
        --size;
    }
    while( aswap );
}

/* sort by scores */
void bubSortScores( char** fns, char** lns, float* scs, int size )
{
    int aswap;
    do
    {
        int i = 1;
        aswap = 0;
        for( ; i < size; ++ i  )
        {
            if( *(scs+i) < *(scs+i-1)  ) /* swap */
            {
                char* tmp;
                float tmpFlt = *(scs+i);
                *(scs+i) = *(scs+i-1);
                *(scs+i-1) = tmpFlt;

                tmp = *(lns+i);
                *(lns+i) = *(lns+i-1);
                *(lns+i-1) = tmp;

                tmp = *(fns+i);
                *(fns+i) = *(fns+i-1);
                *(fns+i-1) = tmp;

                aswap = 1;
            }
        }
        --size;
    }
    while( aswap );
}


float median( float* scs, int size )
{
    int i = size;
    float med = 0;

    if( i % 2 == 0 )
    {
        i /= 2;
        med = ( *(scs+i) + *(scs+i-1) )/ 2.0;
    }
    else
    {
        i /= 2;
        med = *(scs+i);
    }

    return med;
}


void enlarge( char*** fns, char*** lns, float** scs, int size )
{
    int i;
    char** tfns = malloc(size*2*sizeof(char*));
    char** tlns = malloc(size*2*sizeof(char*));
    float* tscs = malloc(size*2*sizeof(float));
    myAssert( (tfns && tlns && tscs), MEMERR );

    /* copy all old over to tnp new ... */
    for( i = 0; i < size; ++ i )
    {
        *(tfns+i) = *(*fns+i);
        *(tlns+i) = *(*lns+i);
        *(tscs+i) = *(*scs+i);
    }

    /* free all ols memory ... */
    free( *fns ); free( *lns ); free( *scs );

    /* update passed in pointers with new values ... */
    *fns = tfns ;
    *lns = tlns ;
    *scs = tscs ;
}




int main() /* ************ BEGIN MAIN ******************* */
{
    char** fnames;
    char** lnames;
    float* scores;
    int i, j, noRecs, quit = 0; /* i holds the size, noRecs holds MAX SIZE */

    printf( "Welcome to the Student Records Information Sytem ...\n" );

    noRecs = takeInInt( "\nNumber of records you want to enter (min is 3): ", 3, 100 );

    fnames = malloc(noRecs*sizeof(char*));
    lnames = malloc(noRecs*sizeof(char*));
    scores = malloc(noRecs*sizeof(float));

    myAssert( (fnames && lnames && scores), MEMERR );

    /* take in some initial student record data ... */
    for( i = 0 ;  ;  )
    {
        takeInRec( fnames+i, lnames+i, scores+i, i );

        ++i;
        if( i == noRecs )
        {
            printf( "\nYou have reached the max capacity of %d\n", i );
            if( tolower(takeInChr( "Enlarge (y/n) ?" )) == 'y' )
            {
                enlarge( &fnames, &lnames, &scores, i );
                noRecs = i*2;
            }
            else break;
        }

        if( !more() ) break;
    }


    do
    {
        int choice = showMenuGetChoice();
        switch(choice)
        {
        case 1: /* print all recs ... */
            for( j = 0; j < i; ++ j )
                showRec( *(fnames+j), *(lnames+j), *(scores+j) );
        break;
        case 2: /* add while still room and more ... */
            if( i == noRecs )
            {
                printf( "\nYou have reached the max capacity of %d\n", i );
                if( tolower(takeInChr( "Enlarge (y/n) ?" )) == 'y' )
                {
                    enlarge( &fnames, &lnames, &scores, i );
                    noRecs = i*2;
                }
                else break;
            }
            for( ; ; )
            {
                takeInRec( (fnames+i), (lnames+i), (scores+i), i );
                ++i;
                if( i == noRecs )
                {
                    printf( "\nYou have reached the max capacity of %d\n", i );
                    if( tolower(takeInChr( "Enlarge (y/n) ?" )) == 'y' )
                    {
                        enlarge( &fnames, &lnames, &scores, i );
                        noRecs = i*2;
                    }
                    else break;
                }
                if( !more() ) break;
            }
        break;
        case 3: /* delete ... findLastName  ... begin at end !!! */
        {
            char* ln = takeInStrMaxLen( "Enter lname to find: ", 20 );
            /* char* fn = takeInStrMaxLen( "Enter fname to find: ", 20 ); */
            /* int k = findFirstLast( fnames, lnames, i, fn, ln ); */

            int k = findLastName( lnames, i, ln );
            int found = (k != -1);
            while( k != -1 )
            {
                printf( "Found name: %s at index %d\n", ln, k );

                /* if delete confirmed ... */
                if( tolower(takeInChr( "Delete (y/n) ? " )) == 'y' )
                {
                    i = deleteIndex( fnames, lnames, scores, i, k );
                    printf( "\nDeleted ok ...\n" );
                }
                else printf( "\nOk ... NOT deleted ...\n" ) ;

                k = findLastName( lnames, i, ln );
            }

            if( !found )
                printf( "\nName %s was NOT found ...\n", ln );

            free( ln );
        }
        break;
        case 4: /* find ALL with lname ... */
        {
            char* ln = takeInStrMaxLen( "Enter lname to find: ", 20 );
            int k = findLastName( lnames, i, ln );
            int found = (k != -1);
            while( k != -1 )
            {
                printf( "\nFound name %s at index %d", ln, k );
                k = findLastName( lnames, k, ln );
            }

            if( !found )
                printf( "\nName %s was NOT found ...", ln );
            putchar( '\n' );
            free( ln );
        }
        break;
        case 5: /* sort by SCORES and show after sorted ... */
             bubSortScores( fnames, lnames, scores, i );
            /* print all recs ... */
            for( j = 0; j < i; ++ j )
                showRec( *(fnames+j), *(lnames+j), *(scores+j) );
        break;
        /* find score //
        {
            float sc = takeInFlt( "Take in score to find: ", 0, 100 );
            int k = findScore( scores, i, sc );
            if( k != -1 )
                printf( "\nFound score %.1f at index %d\n", sc, k );
            else
                printf( "\nScore %.1f was NOT found ...\n", sc );
        }
        */
        case 6: /* sort by LAST NAMES and show after sorted ... */
            bubSortLastName( fnames, lnames, scores, i );
            /* print all recs ... */
            for( j = 0; j < i; ++ j )
                showRec( *(fnames+j), *(lnames+j), *(scores+j) );

        break;
        case 7:
            /* sort ... */
            bubSortScores( fnames, lnames, scores, i );
            printf( "Median score was %.1f\n", median( scores, i ) );
            printf( "There are %d students above this score.\n", i/2 );
        break;
        case 0:
            printf( "\nExiting ...\n");
            quit = 1;
        break;
        default:
            printf( "\nInvalid choice\n" );
        }
    }
    while( ! quit );


    /* free all ('still unfreed') dynamic memory */

    free( scores );
    for( j = i-1; j >= 0; -- j ) free( lnames[j] );
    free( lnames );
    for( j = i-1; j >= 0; -- j ) free( fnames[j] );
    free( fnames );

    return 0;

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

As suggested above, this type of data record processing problem is handled much more easily and cleanly ...

by using a C struct (a data record)

and a readily expandable dynamic array ( a C vec with functions ) ...

Take a look ... and compare :)

Note, the 3 custom C utility functions used here are freely available ( see embedded links in example program below ) ...

/* CvecOfStructVersion.c */  /* 2015-08-03 */


/*
    Note: this 'solution' uses the 3 custom C utility files:
    readLine.h, Cvec.h, Cvec_func's
    Please see comments and links below to freely obtain copies ...
*/
#define EPSILON pow( 10.0, -6 )

#include <math.h>

#include "readLine.h"
/*
    NOTE! the include file readLine.h ... IS freely available at:
    http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864
*/

/* firstly define ... */
typedef struct myRec
{
    char* fname;
    char* lname;
    float score;
} Rec ;

void freeVrec( Rec* rc )
{
    free( rc->lname );
    free( rc->fname );
}

/* NOW .... ok to include ... */
#include "Cvec.h"
#include "Cvec_func's.h"
/*
"Cvec.h" is available at:
http://developers-heaven.net/forum/index.php/topic,2580.msg2862.html#msg2862
"Cvec_func's.h" is available at:
http://developers-heaven.net/forum/index.php/topic,2580.msg2866.html#msg2866
*/


void showRec( const Rec* rc )
{
    printf( "First name: %-20s Last name: %-20s Score: %5.1f \n", rc->fname, rc->lname, rc->score );
}
void showCvec( const Cvec* cv )
{
    int i;
    for( i = 0; i < cv->size; ++ i ) showRec( &cv->ary[i] );
}


/* next 2 functions are used in sorting the Cvec ... */
int cmpScores( const Rec* a, const Rec* b )
{
    float tmp = a->score - b->score;
    if( fabs( tmp ) < EPSILON ) return 0; /* i.e. take  as equal ...*/
    if( tmp < 0 ) return -1;
    return 1;
}
int cmpLastNames( const Rec* a, const Rec* b )
{
    return strcmp( a->lname, b->lname );
}



/* 2 handy utilities for many C student coding problems ... */
int takeInChr( const char* msg )
{
    char chr;
    printf( msg ); fflush( stdout );
    chr = getchar();
    if( chr != '\n' ) while( getchar() != '\n' ) ; /* flush stdin ... */
    return chr;
}
int more() /* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered */
{
    int c = takeInChr( "More (y/n) ? " );
    if( c == 'n' || c == 'N' ) return 0;
    /* else ... */
    return 1;
}


/* a simple student way to handle numeric input ...
   so program won't crash on bad input */
int takeInInt( const char* msg, int myMin, int myMax )
{
    int good = 0, val = 0;
    while( !good )
    {
        printf( msg ); fflush( stdout );

        if( scanf( "%d", &val ) == 1 && getchar() == '\n' ) good = 1;
        else
        {
            printf( "\nInteger input only here please ...\n" );
            while( getchar() != '\n' ) ; /* flush stdin ... */
        }

        if( good && ( val < myMin || val > myMax ) )
        {
            good = 0;
            printf( "\nValid input only in range %d..%d\n", myMin, myMax );
        }
    }
    return val;
}

/* a simple student way to handle numeric input ...
   so program won't crash on bad input */
float takeInFlt( const char* msg, float myMin, float myMax )
{
    int good = 0;
    float val = 0;
    while( !good )
    {
        printf( msg ); fflush( stdout );

        if( scanf( "%f", &val ) == 1 && getchar() == '\n' ) good = 1;
        else
        {
            printf( "\nNumbers only here please ...\n" );
            while( getchar() != '\n' ) ; /* flush stdin ... */
        }

        if( good && ( val < myMin || val > myMax ) )
        {
            good = 0;
            printf( "\nValid input only in range %.1f..%.1f\n", myMin, myMax );
        }
    }
    return val;
}

/* using readLine and getting new dynamic memory ... so can return address */
char* takeInStrMaxLen( const char* msg, unsigned maxLen )
{
    char* p = NULL;

    for( ; ; )
    {
        fputs( msg, stdout ); fflush( stdout );

        p = readLine( stdin );

        if( p[0] && strlen( p ) <= maxLen )
            break;

        else if( !p[0] ) printf( "\nBlank line NOT valid input here ... \n" );
        else printf( "\nFor '%s', max len of %u char's was exceeded ... \n",
                     p, maxLen );

        free( p ); /* try again ... */
    }

    return p;
}


void takeInRec( Rec* rc, int i )
{
    char buf[132];

    sprintf( buf, "\nEnter fname of student %d: ", i+1 );
    rc->fname = takeInStrMaxLen( buf, 20 );

    sprintf( buf, "Enter lname of student %d: ", i+1 );
    rc->lname = takeInStrMaxLen( buf, 20 );

    sprintf( buf, "Enter score for student %d: ", i+1 );
    rc->score = takeInFlt( buf, 0, 100 );
}


int showMenuGetChoice()
{
    putchar( '\n' );
    printf( "<1> Print all records\n" );
    printf( "<2> Add new records\n" );
    printf( "<3> Delete all records with a specified last name\n" );
    printf( "<4> Find all records with a specified last name\n" );
    printf( "<5> Sort by score\n" );
    printf( "<6> Sort by last name\n" );
    printf( "<7> Find median score\n" );
    printf( "<0> Exit the program\n" );
    return takeInInt( "Pleasee enter choice in range 0..7 : ", 0, 7 );
}

int findLastName( const Cvec* cv, const char* name, int lastIndex )
{
    int i = lastIndex;
    for(  ; i >= 0; -- i )
    {
        if( strcmp( cv->ary[i].lname, name ) == 0 ) return i;
    }
    /* if reach here ... */
    return -1;
}

int findScore( const Cvec* cv, float score )
{
    int i = 0;
    for(  ; i < cv->size; ++ i )
    {
        if( fabs( cv->ary[i].score - score) < EPSILON ) return i;
    }
    /* if reach here ... */
    return -1;
}

/* just a wrapper to permit old calling function/name ... */
int deleteIndex( Cvec* cv, int index )
{
    eraseCvec( cv, index );
    return cv->size;
}


float median( const Cvec* cv )
{
    int i = cv->size;
    if( i )
    {
        if( i == 1 ) return cv->ary[0].score;

        if( (i % 2) == 0 )
        {
            i /= 2;
            return ( cv->ary[i].score + cv->ary[i-1].score )/ 2.0;
        }

        /* if reach here ... than there is an ODD number of score ... */

        i /= 2;
        return cv->ary[i].score ;
    }
    printf( "\nNo median ... since no scores ...\n\n" );
    return 0;
}





int main() /* ************ BEGIN MAIN ******************* */
{
    int i, quit = 0;
    Rec rc;
    Cvec cv;
    initCvec( &cv );

    printf( "Welcome to the Student Records Information Sytem ...\n" );

    /* take in some initial student record data ... */
    for( i = 0 ;  ; )
    {
        takeInRec( &rc, i );
        push_backCvec( &cv, &rc );
        ++i;
        if( !more() ) break;
    }


    do
    {
        int choice = showMenuGetChoice();
        switch(choice)
        {
        case 1: /* print all recs ... */
             showCvec( &cv );
        break;
        case 2: /* add while more ... */
            for( ; ; )
            {
                takeInRec( &rc, i );
                push_backCvec( &cv, &rc );
                ++i;
                if( !more() ) break;
            }
        break;
        case 3: /* delete ... findLastName  ... begin at end !!! */
        {
            char* ln = takeInStrMaxLen( "Enter lname to find: ", 20 );
            int k = findLastName( &cv, ln, cv.size-1 );
            int found = (k != -1);
            while( k != -1 )
            {
                printf( "Found name: %s at index %d\n", ln, k );

                /* if delete confirmed ... */
                if( tolower(takeInChr( "Delete (y/n) ? " )) == 'y' )
                {
                    i = deleteIndex( &cv, k );
                    printf( "\nDeleted ok ...\n" );
                }
                else printf( "\nOk ... NOT deleted ...\n" ) ;

                k = findLastName( &cv, ln, k-1 );
            }

            if( !found )
                printf( "\nName %s was NOT found ...\n", ln );

            free( ln );
        }
        break;
        case 4: /* find ALL with last name 'lname' ... */
        {
            char* ln = takeInStrMaxLen( "Enter last name to find: ", 20 );
            int k = findLastName( &cv, ln, cv.size-1 );
            int found = (k != -1);
            while( k != -1 )
            {
                printf( "\nFound name %s at index %d", ln, k );
                k = findLastName( &cv, ln, k-1 );
            }

            if( !found )
                printf( "\nName %s was NOT found ...", ln );
            putchar( '\n' );
            free( ln );
        }
        break;
        case 5: /* sort by SCORES and show after sorted ... */
             msortCvec( &cv, cmpScores );
            /* print all recs ... */
            showCvec( &cv );
        break;
        case 6: /* sort by LAST NAMES and show after sorted ... */
            msortCvec( &cv, cmpLastNames );
            /* print all recs ... */
            showCvec( &cv );
        break;
        case 7:
            /* firstly ensure sorted by scores ... */
            msortCvec( &cv, cmpScores );
            showCvec( &cv );
            printf( "\nMedian score was %.1f\n", median( &cv ) );
            printf( "There are %d student(s) above this score.\n", cv.size/2 );
        break;
        case 0:
            printf( "\nExiting ...\n");
            quit = 1;
        break;
        default:
            printf( "\nInvalid choice\n" );
        }
    }
    while( ! quit );


    /* free all ('still unfreed') dynamic memory */

    clearCvec( &cv );

    return 0;

} /* ********************* END MAIN ********************* */
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.