14 Replies - 2901 Views - Last Post: 28 July 2010 - 10:14 PM Rate Topic: -----

#1 Guest_BJ*


Reputation:

Sort an array of structures and create reports

Posted 23 July 2010 - 10:16 AM

I'm having trouble figuring out how to get started on this project. It needs to be able to write a program to read a file of records into an array of structures, sort them and allow the user to print reports based on a menu selection and further input. Here is an example of what it is supposed to look like... I'm only asking for some guidelines on how i can start this... Thanks for all the help

There are xx records available.

The actions available are:
1. Sort the records by the Student Name field.
2. Sort the records by the Student ID field.
3. Print a report of the records.
4. Search for a record by Student name and print the record.
5. Search for a record by Student ID and print the record.
6. Quit
Enter the number corresponding to the action that you want to perform:

Enter the number corresponding to the action that you want to perform: 3

+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Student Name        | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |
+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Cool, Joe           | 532598 |  100   |   43   |   68   |   88   |   75   |  74.80  |   C   |
| Student, Good       | 579301 |  100   |   98   |  100   |   95   |   99   |  98.40  |   A   |

      . . .
+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+


Is This A Good Question/Topic? 0

Replies To: Sort an array of structures and create reports

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,548
  • Joined: 23-August 08

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 10:40 AM

Post the code you've written, and what you're having problems with. If you can't even get started, then I'd suggest going to the instructor for assistance; it's for what you're paying him. Post your code in code tags, like so:

:code:
Was This Post Helpful? 0
  • +
  • -

#3 Guest_BJ*


Reputation:

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 11:47 AM

Heres what I was able to write so far...


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#define ARRAY_MAX   100     // Maximum number of records in the array of structures
#define LINE_MAX    200     // Maximum length of an input line
#define NAME_LEN    25      // Name field length
#define ID_LEN       6      // Student ID length
#define AVG_LEN      6      // Average field length
#define GRADE_LEN   2       // Grade field length

typedef struct  
{
	char name[NAME_LEN+1];
	int id;
	int test1;
	int test2;
	int proj1;
	int proj2;
	int proj3;
	float average[AVG_LEN+1];
	char grade[GRADE_LEN+1];
	int ext;
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);

int main(void)
{
	FILE* fp;					// Pointer to the input file
	int count=0;			    // Number of records read into the array.
	int i;						// Loop index
	int rc;						// scanf return code
	STUDREC records[ARRAY_MAX];
	
	
	// Open the file for read and print an error message and exit if that fails.
	fp = fopen("student_data", "r");
	if( fp == 0 )
	{
		printf("\nError: Could not open file address_data for read.\n\n");
		return(1);
	}
	
	count = readRecords(records, ARRAY_MAX, fp);
	
	if( count == 0)
	{
		printf("\nThere were 0 valid records found in file student_data.\n\n");
		return(2);
	}

	printRecords(records, count);

	return(0);
	} // main
	
/*
 * Function Name: readRecords
 *
 * Input Parameters: records   - Array of structures to place data read in
 *                   maxrecs   - max records to read
 *                   fp        - file pointer
 *
 * Description:
 *
 * Return Value: the number of valid records read
 */
 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX];
	int rc;
	int count=0;
	
	while(fgets(line, LINE_MAX, fp) != NULL)
	{
		rc = sscanf(line,"%25[^|]%*[|]%100[^|]%*[|]%25[^|]%*[|]%2[^|]%*[|]%d%*[|]%3d%3d%4d",
			records[count].name, records[count].id, records[count].test1,
			records[count].test2, &records[count].proj1, &records[count].proj2,
            &records[count].proj3, &records[count].average, &records[count].grade, &records[count].ext);
			if( (rc != 10) || records[count].id < 100000 || records[count].id > 999999) 
			{
			printf("Invalid Record: %s", line);
		}
		else
		{
            count++;
			if(count == ARRAY_MAX)break;
		}
		}
	    return(count);
	}
	
/*
 * Function Name: printRecords
 *
 * Input Parameters: array     - Array of structures to print
 *                   count     - number of values in the array
 *
 * Description:
 *
 * Return Value: none
 */
 
 void printRecords(STUDREC records[], int count)
{
	int i=0;
	for ( i = 0; i < count; i++ )
	{
		printf("\nName:    %s\nID: %d\nTest 1: %d\nTest 2: %d\nProj 1: %d\nProj 2: %d\nProj 3: %d\nAverage: %f\nGrade: %c\n",
			records[i].name, records[i].id, records[i].test1,
			records[i].test2, records[i].proj1, records[i].proj2,
            records[i].proj3, records[i].average, records[i].grade, records[i].ext);
	}
	return;
} //printRecords
void main()
{
  int c;
  
  while(c!=6)
   {  
     printf("There are %d records available.\n");
     printf("The actions available are:\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n\n--");
	 printf(" Enter the number corresponding to the action that you want to perform:%d\n");
	 
     scanf("%d",&c);
     
     switch(c)
	 {
	 case 1:
		  filewrite();
		  break;
	 case 6:
		
		  break;
	 default:
		  break;
	 }
    }

  }


Was This Post Helpful? 0

#4 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 01:04 PM

Did you write your code, or copy paste it from other sources?

Because you have two mains. It looks like you got started twice, and then just merged the two files of code together. Which no programmer does, unless you never wrote the code yourself.

Sorry, but if you can't qualify your question, with anything more than a dump of your assignment and a request for "help", you aren't getting help.
Was This Post Helpful? 0
  • +
  • -

#5 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,548
  • Joined: 23-August 08

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 01:48 PM

There are also a lot of content regarding sorting in our tutorials section.
Was This Post Helpful? 0
  • +
  • -

#6 Guest_BJ*


Reputation:

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 01:58 PM

Ya my professor gave us an Example of using structures so i did try and use pieces of the example and my own stuff to piece together what you see... So yes you are correct in the fact that it looks like I started twice b/c I did...lol but I did ask for help on the project not critcism for not knowing how to code :bigsmile:
Was This Post Helpful? 0

#7 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 23 July 2010 - 09:06 PM

View PostBJ, on 23 July 2010 - 02:58 PM, said:

Ya my professor gave us an Example of using structures so i did try and use pieces of the example and my own stuff to piece together what you see... So yes you are correct in the fact that it looks like I started twice b/c I did ... :bigsmile:


The first thing is to get a firm handle on how YOUR data file is structured.

In the following example, edited from your code above, the assumptions are that the data is a little unstructured ...

For example, the name field should have at max 25 char's, (as your code suggests), but the data may look like this in file lines ...

Smith, Sam 123456 ....restOfLine...

or

Joe, Cool I. 123457 ...restOfLine...

or

Perry, LongFirstNameThatWillBeChoppedAt25Characters 123458 ...rest...

And ... that spaces ONLY are used between fields.

The test data file was called: studentData100723.txt

... and looked like this:
Cool, Joe I.    532598 100     43      68      88      75      74.80  C
Student, SammyGoodTwoShoes... 579301 100     98      100     95      99      98.40  A
Bad Data Line (no numbers) ..........................................................



This may give you some more ideas about data handling to draw from ...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> // re. isdigit
//#include <stdbool.h> // not used here ...


#define ARRAY_MAX_SIZE 100  // Max num of records in the array
#define LINE_MAX_LEN   200  // Max length of an input line
#define NAME_MAX_LEN    25  // Max num of char's in a name

#define DATA_FILE "studentData100723.txt"
/*
Cool, Joe I.    532598 100     43      68      88      75      74.80  C
Student, SammyGoodTwoShoes... 579301 100     98      100     95      99      98.40  A
Bad Data Line (no numbers) ..........................................................
*/

typedef struct
{
	char name[NAME_MAX_LEN+1];
	int id;
	int test[2];
	int proj[3];
	float average;
	char grade;
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);

int showMenuGetChoice( STUDREC records[], int count );

int main(void)
{
	FILE* fp;      // Pointer to the input file
	int count=0;   // Number of records read into the array.
	STUDREC records[ARRAY_MAX_SIZE];

	// Open the file for read and print an error message and exit if that fails.
	fp = fopen( DATA_FILE, "r");
	if( fp == 0 )
	{
		printf("\nError: Could not open file address_data for read.\n\n");
		getchar();
		return(1);
	}

	count = readRecords( records, ARRAY_MAX_SIZE, fp );
	
	if( count == 0 )
	{
		printf("\nThere were 0 valid records found in file student_data.\n\n");
		getchar();
		return(2);
	}

	//printRecords(records, count);
	showMenuGetChoice( records, count );
	
	printf( "\nPress 'Enter' to continue ... " );
	while( getchar() != '\n' );
	getchar();
	
	return(0);
} // main

/*
 * Function Name: readRecords
 *
 * Input Parameters: records   - Array of structures to place data read in
 *                   maxrecs   - max records to read
 *                   fp        - file pointer
 *
 * Description:
 *
 * Return Value: the number of valid records read ... AND
                 ... the new records in the array
 */
 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX_LEN];
	int rc;
	int i = 0;

	while( fgets(line, LINE_MAX_LEN, fp) != NULL )
	{
        int len;
        char *p = line;
        char gradeStr[16];
        
        // extract name ...
        while( *p != 0 && !isdigit(*p) )
            p++;
        if( *p == '\0' ) // invalid data (no digits in line)
        {
		    printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
		    break;
        }
        
        // now trim any trailing spaces ...
        while( *(--p) == ' ' ) ; // back up to last char in name
        // and move forward one-past-end ...
        ++p;

        len = p - line;
        if( len <= NAME_MAX_LEN )
        {
            strncpy( records[i].name, line, len );
            records[i].name[len] = '\0';
        }
        else
        {
            strncpy( records[i].name, line, NAME_MAX_LEN );
            records[i].name[NAME_MAX_LEN] = '\0';
        }

        // rest of data: 6 ints, 1 float and a final string
		rc = sscanf( p, "%d%d%d%d%d%d%f%s",
			         &records[i].id,
                     &records[i].test[0], &records[i].test[1],
                     &records[i].proj[0], &records[i].proj[1],
                     &records[i].proj[2],
                     &records[i].average,  gradeStr ) ;
            
			if( (rc != 8) || records[i].id < 100000 ||
                 records[i].id > 999999 )
            {
			    printf( "Invalid Record:\n %s\nAborting read ...\n",
                        line );
                break;
            }

        // extract grade letter from last string at line end
        p = gradeStr;
        while( *p == ' ' ) p++;
        records[i].grade = *p;
        
        i++;
		if( i == ARRAY_MAX_SIZE )
            break;
	}
	return i ;
}

/*
 * Function Name: printRecords
 *
 * Input Parameters: array     - Array of structures to print
 *                   count     - number of values in the array
 *
 * Description:
 *
 * Return Value: none
 */

void printRecords(STUDREC records[], int count)
{
    char formatStr[] =
    "\nName    :  %s\n"
    "ID      :  %d\n"
    "Test 1  :  %3d,   "
    "Test 2  :  %3d\n"
    "Proj 1  :  %3d,   "
    "Proj 2  :  %3d,   "
    "Proj 3  :  %3d\n"
    "Average :  %6.2f "
    "Grade   :  %c\n";
    
	int i=0;
	for ( i = 0; i < count; i++ )
	{
		printf( formatStr,
			records[i].name, records[i].id,
            records[i].test[0],	records[i].test[1],
            records[i].proj[0], records[i].proj[1],
            records[i].proj[2], records[i].average,
            records[i].grade);
	}
	return;
} //printRecords


//#if 0 // to tell compiler to skip this section ...
int showMenuGetChoice( STUDREC records[], int count )
{
  int c = -1;
  while( c != 6 )
  {
     printf("\nThere are %d records available.\n\n", count );
     printf("The jobs available are ...\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student Name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n");
	 printf("Enter number (1..6) of job to perform: ");
	 fflush( stdin );
	 
	 c = -1; /* error value if scanf fails ... */
     scanf( "%d", &c );

     switch( c )
	 {
	 case 3  : printRecords(records, count); break;
	 case 6  : puts( "\nOk ... exiting program now ..." ); return 0;
	 default : printf( "\nNot implemented yet ...  " );
	 }
  }
  return c;
}
//#endif

This post has been edited by David W: 23 July 2010 - 09:57 PM

Was This Post Helpful? 1
  • +
  • -

#8 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 24 July 2010 - 12:57 AM

Here's an other example of 'read/display' of data structured similar to yours ...

It shows a way to parse a line that has each field delimited with a '|' character.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> // re. isdigit


// NOTE 1: For this example, the data is quite structured
// with fields beginning and ending with a '|' char

// NOTE 2: Here it seems that one wants to store only a max
// of 20 char's for the name ... but may read a longer name
// until 'name-field-end' (the terminal '|' char) is reached.

#define NAME_MAX_LEN    20  // Max num of char's in a name

#define ARRAY_MAX_SIZE 100  // Max num of records in the array
#define LINE_MAX_LEN   200  // Max length of an input line

#define DATA_FILE "studentData100724.txt"
/*
| Cool, Joe I.        | 532598 |  100   |   43   |   68   |   88   |   75   |  74.80  |   C   |
| Student, GoodExtendedVeryLongFirstName | 579301 |  100   |   98   |  100   |   95   |   99   |  98.40  |   A   |
Bad Data Line  ..........................................................
+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
0         1         2         3         4         5         6         7         8         9   9

  12345678901234567890 12345678 12345678 12345678 12345678 12345678 12345678 123456789 1234567
+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Student Name        | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |
+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+

*/

typedef struct
{
	char name[NAME_MAX_LEN+1];
	int id;
	int test[5];
	float average;
	char grade;
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);

int showMenuGetChoice( STUDREC records[], int count );

int main(void)
{
	FILE* fp;      // Pointer to the input file
	int count=0;   // Number of records read into the array.
	STUDREC records[ARRAY_MAX_SIZE];

	// Open the file for read and print an error message and exit if that fails.
	fp = fopen( DATA_FILE, "r");
	if( fp == 0 )
	{
		printf( "\nError! Could not open file %s to read.\n\n",
                DATA_FILE );
		getchar();
		return(1);
	}

	count = readRecords( records, ARRAY_MAX_SIZE, fp );
	
	if( count == 0 )
	{
		printf( "\nNO valid records found in file %s.\n\n",
                DATA_FILE );
		getchar();
		return(2);
	}

	//printRecords(records, count);
	showMenuGetChoice( records, count );
	
	printf( "\nPress 'Enter' to continue ... " );
	while( getchar() != '\n' );
	getchar();
	
	return(0);
} // main

/*
 * Function Name: readRecords
 *
 * Input Parameters: records   - Array of structures to place data read in
 *                   maxrecs   - max records to read
 *                   fp        - file pointer
 *
 * Description:
 *
 * Return Value: the number of valid records read ... AND
                 ... the new records in the array
 */
 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX_LEN];
	int i = 0;

	while( fgets(line, LINE_MAX_LEN, fp) != NULL )
	{
        int j, len;
        char *p, *q, *end;
        p = q = line;
        
        // extract name ... first ... skip over '|' and ' '
        while( *p != 0 && ( *p =='|' || *p == ' ' ) )
            ++p; // advance ...
        if( *p == '\0' ) // invalid data (no '|' char)
        {
		    printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
		    break;
        }

        q = p; // p is start of name field, q to hold 1_past_end
        while( *q != 0 && *q != '|' )
            ++q;
        if( *q == '\0' ) // invalid data (no '|' char)
        {
		    printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
		    break;
        }
        // now trim any trailing  ' ' char's ...
        end = q;
        while( *(--end) == ' ' ) ; // back up to last_char_in_name
        // now move to one_past_last_char
        ++end;

        // ensure <= max of char's is stored in name
        len = end - p;
        if( len <= NAME_MAX_LEN ) // ok ... copy all ...
        {
            strncpy( records[i].name, p, len );
            records[i].name[len] = '\0';
        }
        else // truncate ... just take the first max char's
        {
            strncpy( records[i].name, p, NAME_MAX_LEN );
            records[i].name[NAME_MAX_LEN] = '\0';
        }

        // now extract 6 ints ... and 1 float
        for( j = 0; j < 7; ++j )
        {
            p = ++q; // advance over last '|' char
            while( *q != 0 && *q != '|' ) ++q ; // advance ...
            end = q;
            while( *(--end) == ' ' ) ; // backup over ' '
            if( *q == '\0' || !isdigit(*end) ) // invalid data (no '|' char)
            {
		        printf( "Invalid Record:\n%s\nAborting read "
                        "now ...\n", line );
		      return i;
            }
            
            if( j == 0 )
            {
                records[i].id = atoi(p);
                if( records[i].id < 100000 || records[i].id > 999999 )
                {
                    printf( "Invalid Record:\n%s\nAborting read "
                        "now ...\n", line );
		            return i;
                }
            }
            else if( j < 6 ) records[i].test[j-1] = atoi(p);
            else records[i].average = atof(p);
        }
        
        ++q; // advance over last '|' ...
        // extract grade letter from last string at line end
        while( *q != 0 && *q == ' ' ) ++q; // advance
        
        if( *q == '\0' ) // invalid data (no '|' char)
        {
	        printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
	      break;
        }
        records[i].grade = *q;
        
        i++;
		if( i == ARRAY_MAX_SIZE )
            break;
	}
	return i ;
}

/*
 * Function Name: printRecords
 *
 * Input Parameters: array     - Array of structures to print
 *                   count     - number of values in the array
 *
 * Description:
 *
 * Return Value: none
 */

void printRecords(STUDREC records[], int count)
{
    char formatStr[] =
    "\nName    :  %s\n"
    "ID      :  %d\n"
    "Test 1  :  %3d,   "
    "Test 2  :  %3d\n"
    "Proj 1  :  %3d,   "
    "Proj 2  :  %3d,   "
    "Proj 3  :  %3d\n"
    "Average :  %6.2f "
    "Grade   :  %c\n";
    
	int i=0;
	for ( i = 0; i < count; i++ )
	{
		printf( formatStr,
			records[i].name, records[i].id,
            records[i].test[0],	records[i].test[1],
            records[i].test[2], records[i].test[3],
            records[i].test[4], records[i].average,
            records[i].grade);
	}
	return;
} //printRecords


//#if 0 // to tell compiler to skip this section ...
int showMenuGetChoice( STUDREC records[], int count )
{
  int c = -1;
  while( c != 6 )
  {
     printf("\nThere are %d records available.\n\n", count );
     printf("The jobs available are ...\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student Name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n");
	 printf("Enter number (1..6) of job to perform: ");
	 fflush( stdin );
	 
	 c = -1; /* error value if scanf fails ... */
     scanf( "%d", &c );

     switch( c )
	 {
	 case 3  : printRecords(records, count); break;
	 case 6  : puts( "\nOk ... exiting program now ..." ); return 0;
	 default : printf( "\nNot implemented yet ...  " );
	 }
  }
  return c;
}
//#endif

Was This Post Helpful? 1
  • +
  • -

#9 Guest_Bj*


Reputation:

Re: Sort an array of structures and create reports

Posted 24 July 2010 - 08:29 AM

david thank you so much for all the help!! You really went above and beyond, I really appreciate it...
-BJ
Was This Post Helpful? 0

#10 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 24 July 2010 - 10:18 PM

View PostBj, on 24 July 2010 - 09:29 AM, said:

david thank you so much for all the help!! ... I really appreciate it...
-BJ


You are welcome ...

You may like to see these snippets that deal with some other aspects of your program ... like sorting a C struct ...

http://www.dreaminco...snippet5070.htm


C qsort compare snippets for struct, string,
... The compare functions needed for struct's using combined fields ...
and string comparisons that ignore case are demo'd here



http://www.dreaminco...snippet5142.htm
/* C 'vector emulation' using a dynamic array of rec's (see demo MENU below) */

#define MENU      " 1. Enter a new record. \n" \
                  " 2. Retrieve a record by name. \n" \
                  " 3. Retrieve a record by phone number. \n" \
                  " 4. Show all records. \n" \
                  " 5. QSort all records by name. \n" \
                  " 6. QSort all records by phone number. \n" \
                  " 7. Chop exact duplicates from records. \n" \
                  " 8. Edit/Delete a record. \n" \
                  " 9. Write new file of sorted unique records. \n" \
                  "10. Exit \n"
#define PROMPT    "Enter a number in range 1 to 10 : "





http://www.dreaminco...snippet3542.htm

C version, using a linked-list of struct Student
C way to approximate class Student ...
with an insert-sorted list and simple password protection.
Note: will only permit unique id's




Updates are maintained here ....

http://developers-he...index.php/topic,106.0.html
Was This Post Helpful? 0
  • +
  • -

#11 Guest_BJ*


Reputation:

Re: Sort an array of structures and create reports

Posted 27 July 2010 - 08:39 AM

Hey david I'm still having a bit of difficulty getting it to print out the properlayout Invalid Record: ID, Bad:98654:100:34:54:21:34:F
Invalid Record: Score, Bad:835747:155:98:95:100:101:A
Invalid Record: Data, Missing:612345:100::99:50::C
Invalid Record: Student, Withnamethatistoolong:711111:100:100:100:100:100:A

There are 12 records available.

The actions available are:
1. Sort the records by the Student Name field.
2. Sort the records by the Student ID field.
3. Print a report of the records.
4. Search for a record by Student name and print the record.
5. Search for a record by Student ID and print the record.
6. Quit
Enter the number corresponding to the action that you want to perform: 3

+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Student Name | ID | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Cool, Joe | 532598 | 100 | 43 | 68 | 88 | 75 | 74.80 | C |
| Slacker, Rufus | 734312 | 65 | 48 | 0 | 68 | 45 | 45.20 | F |
| Smart, Maxwell | 865868 | 55 | 64 | 99 | 99 | 79 | 79.20 | C+ |
| Bond, James | 700007 | 85 | 86 | 90 | 95 | 85 | 88.20 | B+ |
| Student, Good | 579301 | 100 | 98 | 100 | 95 | 99 | 98.40 | A |
| Smith, John | 571894 | 85 | 73 | 89 | 85 | 87 | 83.80 | B |
| Doe, Jane | 690112 | 93 | 87 | 73 | 74 | 81 | 81.60 | B- |
| Dropout, College | 735347 | 54 | 0 | 67 | 0 | 0 | 24.20 | W |
| Student, Solid | 536267 | 95 | 93 | 87 | 94 | 96 | 93.00 | A |
| Student, Perfect | 511111 | 100 | 100 | 100 | 100 | 100 | 100.00 | A |
| Zappa, Zelda | 999999 | 87 | 88 | 89 | 90 | 89 | 88.60 | B+ |
| Abba, Abby | 500000 | 1 | 2 | 3 | 4 | 5 | 3.00 | F |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+ here's how i've been trying to get it to look like, any insight??
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> 



#define ARRAY_MAX_SIZE 100  // Max num of records in the array
#define LINE_MAX_LEN   200  // Max length of an input line
#define NAME_MAX_LEN    25  // Max num of char's in a name

#define DATA_FILE "studentData.txt"

typedef struct
{
	char name[NAME_MAX_LEN+1];
	int id;
	int test[2];
	int proj[3];
	float average;
	char grade;
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);
int showMenuGetChoice( STUDREC records[], int count );

int main(int argc, char* argv[])
{
	FILE* fp;      // Pointer to the input file
	int count=0;   // Number of records read into the array.
	STUDREC records[ARRAY_MAX_SIZE];

	// Open the file for read and print an error message and exit if that fails.
	if( argc > 1 )fp = fopen( argv[1], "r");
	if( fp == 0 )
	{
		printf("\nError: Could not open file student_data for read.\n\n");
		getchar();
		return(1);
	}

	count = readRecords( records, ARRAY_MAX_SIZE, fp );
	
	if( count == 0 )
	{
		printf("\nThere were 0 valid records found in file student_data.\n\n");
		printf( "\nPress 'Enter' to Exit ... " );
		getchar();
		return(2);
	}

	//printRecords(records, count);
	showMenuGetChoice( records, count );
	
	printf( "\nPress 'Enter' to continue ... " );
	while( getchar() != '\n' );
	getchar();
	
	return(0);
} // main

/*
 * Function Name: readRecords
 *
 * Input Parameters: records   - Array of structures to place data read in
 *                   maxrecs   - max records to read
 *                   fp        - file pointer
 *
 * Description:
 *
 * Return Value: the number of valid records read ... AND
                 ... the new records in the array
 */
 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX_LEN];
	int rc;
	int i = 0;

	while( fgets(line, LINE_MAX_LEN, fp) != NULL )
	{
        int len;
        char *p = line;
        char gradeStr[16];
        
       
        while( *p != 0 && !isdigit(*p) )
            p++;
        if( *p == '\0' ) 
        {
		    printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
		    break;
        }
        
        while( *(--p) == ' ' ) ;
        ++p;

        len = p - line;
        if( len <= NAME_MAX_LEN )
        {
            strncpy( records[i].name, line, len );
            records[i].name[len] = '\0';
        }
        else
        {
            strncpy( records[i].name, line, NAME_MAX_LEN );
            records[i].name[NAME_MAX_LEN] = '\0';
        }

		rc = sscanf( p, "%d%d%d%d%d%d%f%s",
			         &records[i].id,
                     &records[i].test[0], &records[i].test[1],
                     &records[i].proj[0], &records[i].proj[1],
                     &records[i].proj[2],
                     &records[i].average,  gradeStr ) ;
					 
           if( (rc != 8) || records[i].id < 500000 ||
                 records[i].id > 999999 || records[i].test[0] < 0 ||
                 records[i].test[0] > 125 || records[i].test[1] < 0 ||
                 records[i].test[1] > 125 || records[i].proj[1] < 0 ||
                 records[i].proj[1] > 125 || records[i].proj[2] < 0 ||
                 records[i].proj[2] > 125)
            {
			    printf( "Invalid Record:\n %s\nAborting read ...\n",
                        line );
                break;
            }

        p = gradeStr;
        while( *p == ' ' ) p++;
        records[i].grade = *p;
        
        i++;
		if( i == ARRAY_MAX_SIZE )
            break;
	}
	return i ;
}

/*
 * Function Name: printRecords
 *
 * Input Parameters: array     - Array of structures to print
 *                   count     - number of values in the array
 *
 * Description:
 *
 * Return Value: none
 */
 
void printRecords(STUDREC records[], int count)
{
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
	printf("\n| Student Name        | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
	
    char formatStr[] =
    "\nName    :  %s\n"
    "ID      :  %d\n"
    "Test 1  :  %3d,   "
    "Test 2  :  %3d\n"
    "Proj 1  :  %3d,   "
    "Proj 2  :  %3d,   "
    "Proj 3  :  %3d\n"
    "Average :  %6.2f "
    "Grade   :  %c\n";
    
	int i=0;
	for ( i = 0; i < count; i++ )
	{
	printf( formatStr,
			records[i].name, records[i].id,
            records[i].test[0],	records[i].test[1],
            records[i].proj[0], records[i].proj[1],
            records[i].proj[2], records[i].average,
            records[i].grade);
	}
	return;
} //printRecords

int showMenuGetChoice( STUDREC records[], int count )
{
  int c = -1;
  while( c != 6 )
  {
     printf("\nThere are %d records available.\n\n", count );
     printf("The jobs available are ...\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student Name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n");
	 printf("Enter number (1..6) of job to perform: ");
	 fflush( stdin );
	 
	 c = -1; 
     scanf( "%d", &c );

     switch( c )
	 { 
	 case 3  : printRecords(records, count); break;
	 case 6  : puts( "\n Exiting program now ..." ); return 0;
	 default : printf( "\nEnter a number of what you want to do ...  " );
	 }
  }
  return c;
}


Was This Post Helpful? 0

#12 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 27 July 2010 - 02:04 PM

View PostBJ, on 27 July 2010 - 09:39 AM, said:

... still having a bit of difficulty getting it to print out the properlayout

Invalid Record: ID, Bad:98654:100:34:54:21:34:F
Invalid Record: Score, Bad:835747:155:98:95:100:101:A
Invalid Record: Data, Missing:612345:100::99:50::C
Invalid Record: Student, Withnamethatistoolong:711111:100:100:100:100:100:A

There are 12 records available.

The actions available are:
1. Sort the records by the Student Name field.
2. Sort the records by the Student ID field.
3. Print a report of the records.
4. Search for a record by Student name and print the record.
5. Search for a record by Student ID and print the record.
6. Quit
Enter the number corresponding to the action that you want to perform: 3

+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Student Name              | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Cool, Joe                 | 532598 |  100   |   43   |   68   |   88   |   75   |  74.80  |   C   |
| Slacker, Rufus            | 734312 |   65   |   48   |    0   |   68   |   45   |  45.20  |   F   |
| Smart, Maxwell            | 865868 |   55   |   64   |   99   |   99   |   79   |  79.20  |   C+  |
| Bond, James               | 700007 |   85   |   86   |   90   |   95   |   85   |  88.20  |   B+  |
| Student, Good             | 579301 |  100   |   98   |  100   |   95   |   99   |  98.40  |   A   |
| Smith, John               | 571894 |   85   |   73   |   89   |   85   |   87   |  83.80  |   B   |
| Doe, Jane                 | 690112 |   93   |   87   |   73   |   74   |   81   |  81.60  |   B-  |
| Dropout, College          | 735347 |   54   |    0   |   67   |    0   |    0   |  24.20  |   W   |
| Student, Solid            | 536267 |   95   |   93   |   87   |   94   |   96   |  93.00  |   A   |
| Student, Perfect          | 511111 |  100   |  100   |  100   |  100   |  100   | 100.00  |   A   |
| Zappa, Zelda              | 999999 |   87   |   88   |   89   |   90   |   89   |  88.60  |   B+  |
| Abba, Abby                | 500000 |    1   |    2   |    3   |    4   |    5   |   3.00  |   F   |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+  



here's how i've been trying to get it to look like, any insight??


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> 



#define ARRAY_MAX_SIZE 100  // Max num of records in the array
#define LINE_MAX_LEN   200  // Max length of an input line
#define NAME_MAX_LEN    25  // Max num of char's in a name

#define DATA_FILE "studentData.txt"

typedef struct
{
	char name[NAME_MAX_LEN+1];
	int id;
	int test[2];
	int proj[3];
	float average;
	char grade;
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);
int showMenuGetChoice( STUDREC records[], int count );

int main(int argc, char* argv[])
{
	FILE* fp;      // Pointer to the input file
	int count=0;   // Number of records read into the array.
	STUDREC records[ARRAY_MAX_SIZE];

	// Open the file for read and print an error message and exit if that fails.
	if( argc > 1 )fp = fopen( argv[1], "r");
	if( fp == 0 )
	{
		printf("\nError: Could not open file student_data for read.\n\n");
		getchar();
		return(1);
	}

	count = readRecords( records, ARRAY_MAX_SIZE, fp );
	
	if( count == 0 )
	{
		printf("\nThere were 0 valid records found in file student_data.\n\n");
		printf( "\nPress 'Enter' to Exit ... " );
		getchar();
		return(2);
	}

	//printRecords(records, count);
	showMenuGetChoice( records, count );
	
	printf( "\nPress 'Enter' to continue ... " );
	while( getchar() != '\n' );
	getchar();
	
	return(0);
} // main

/*
 * Function Name: readRecords
 *
 * Input Parameters: records   - Array of structures to place data read in
 *                   maxrecs   - max records to read
 *                   fp        - file pointer
 *
 * Description:
 *
 * Return Value: the number of valid records read ... AND
                 ... the new records in the array
 */
 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX_LEN];
	int rc;
	int i = 0;

	while( fgets(line, LINE_MAX_LEN, fp) != NULL )
	{
        int len;
        char *p = line;
        char gradeStr[16];
        
       
        while( *p != 0 && !isdigit(*p) )
            p++;
        if( *p == '\0' ) 
        {
		    printf( "Invalid Record:\n%s\nAborting read "
                    "now ...\n", line );
		    break;
        }
        
        while( *(--p) == ' ' ) ;
        ++p;

        len = p - line;
        if( len <= NAME_MAX_LEN )
        {
            strncpy( records[i].name, line, len );
            records[i].name[len] = '\0';
        }
        else
        {
            strncpy( records[i].name, line, NAME_MAX_LEN );
            records[i].name[NAME_MAX_LEN] = '\0';
        }

		rc = sscanf( p, "%d%d%d%d%d%d%f%s",
			         &records[i].id,
                     &records[i].test[0], &records[i].test[1],
                     &records[i].proj[0], &records[i].proj[1],
                     &records[i].proj[2],
                     &records[i].average,  gradeStr ) ;
					 
           if( (rc != 8) || records[i].id < 500000 ||
                 records[i].id > 999999 || records[i].test[0] < 0 ||
                 records[i].test[0] > 125 || records[i].test[1] < 0 ||
                 records[i].test[1] > 125 || records[i].proj[1] < 0 ||
                 records[i].proj[1] > 125 || records[i].proj[2] < 0 ||
                 records[i].proj[2] > 125)
            {
			    printf( "Invalid Record:\n %s\nAborting read ...\n",
                        line );
                break;
            }

        p = gradeStr;
        while( *p == ' ' ) p++;
        records[i].grade = *p;
        
        i++;
		if( i == ARRAY_MAX_SIZE )
            break;
	}
	return i ;
}

/*
 * Function Name: printRecords
 *
 * Input Parameters: array     - Array of structures to print
 *                   count     - number of values in the array
 *
 * Description:
 *
 * Return Value: none
 */
 
void printRecords(STUDREC records[], int count)
{
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
	printf("\n| Student Name        | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
	
    char formatStr[] =
    "\nName    :  %s\n"
    "ID      :  %d\n"
    "Test 1  :  %3d,   "
    "Test 2  :  %3d\n"
    "Proj 1  :  %3d,   "
    "Proj 2  :  %3d,   "
    "Proj 3  :  %3d\n"
    "Average :  %6.2f "
    "Grade   :  %c\n";
    
	int i=0;
	for ( i = 0; i < count; i++ )
	{
	printf( formatStr,
			records[i].name, records[i].id,
            records[i].test[0],	records[i].test[1],
            records[i].proj[0], records[i].proj[1],
            records[i].proj[2], records[i].average,
            records[i].grade);
	}
	return;
} //printRecords

int showMenuGetChoice( STUDREC records[], int count )
{
  int c = -1;
  while( c != 6 )
  {
     printf("\nThere are %d records available.\n\n", count );
     printf("The jobs available are ...\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student Name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n");
	 printf("Enter number (1..6) of job to perform: ");
	 fflush( stdin );
	 
	 c = -1; 
     scanf( "%d", &c );

     switch( c )
	 { 
	 case 3  : printRecords(records, count); break;
	 case 6  : puts( "\n Exiting program now ..." ); return 0;
	 default : printf( "\nEnter a number of what you want to do ...  " );
	 }
  }
  return c;
}



1. the assumption here, seems to be, that your data file uses spaces to separate each field

2. you can add a 'ext' char to the struct for the + or - value ... or, perhaps, simpler, just change field from 'char grade;' to 'char grade[3];' ... to hold 2 char's, like A+, and the '\0'

3. rather then break on a parsing error ... send that line, and error code, to a printBadDataLine function that will format the error printout at the top of your display, when your program fist runs and is reading in the file into an array of struct of VALID data...

Note: on a bad data line the 'i' counter would NOT be incremented at the bottom of the loop (you could set a flag at the top then check at bottom if bad data ...
// top
int  badData = 0;

// ...

// bottom
if( !badData ) ++i; // the increment valid data count


This post has been edited by David W: 27 July 2010 - 02:17 PM

Was This Post Helpful? 0
  • +
  • -

#13 Guest_BJ*


Reputation:

Re: Sort an array of structures and create reports

Posted 27 July 2010 - 06:02 PM

Sorry I'm still not understanding how that will print out the table and menu properly? The code I have is only printing out one line of invalid data it's not prompting the menu or even printing out the student name id etc... im lost...
Was This Post Helpful? 0

#14 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 27 July 2010 - 07:40 PM

View PostBJ, on 27 July 2010 - 07:02 PM, said:

Sorry I'm still not understanding how that will print out the table and menu properly? The code I have is only printing out one line of invalid data it's not prompting the menu or even printing out the student name id etc... im lost...



Did you NOTE: The code you copied above ... did a "break;" at every bad data ... as I restated in the last post.

As I implied in the last post ... take out that "break;" and replace it with a call to a new function you need to write ... a void function that prints out that bad line formatted the way you want for that bad line ... then returns ... so you can read the next line.

Pass the whole line ... and the error code ... (make some up with defines or enum ... for each type of error message you wish printed)
Was This Post Helpful? 0
  • +
  • -

#15 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Sort an array of structures and create reports

Posted 28 July 2010 - 10:14 PM

Actually you don't need error codes ... and just pass the part of the file line that begins at the ID (pass a pointer/an address).

The following re-edit may give you some more ideas ...

(The .txt data file used is attached below.)

The presumption here is:

- each data line has a name field ... that ends just before the first digit in the following id number, but should be 25 char's or less ... followed by a 6 digit id ... then a space ... then 5 more int's spaced out with valid range 0..125

- there may be more data at the end of a line ... but this is ignored during the initial file read.


// fileDataLineValidation.c //

// example ... of parsing a data file
// see attached text file: studentData.txt

/*
Invalid Record: ID, Bad:98654:100:34:54:21:34:F
Invalid Record: Score, Bad:835747:155:98:95:100:101:A
Invalid Record: Data, Missing:612345:100::99:50::C
Invalid Record: Student, Withnamethatistoolong:711111:100:100:100:100:100:A

There are 12 records available.

The actions available are:
1. Sort the records by the Student Name field.
2. Sort the records by the Student ID field.
3. Print a report of the records.
4. Search for a record by Student name and print the record.
5. Search for a record by Student ID and print the record.
6. Quit
Enter the number corresponding to the action that you want to perform: 3

+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Student Name              | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
| Cool, Joe I.              | 532598 |  100   |   43   |   68   |   88   |   75   |  74.80  |   C   |
| Slacker, Rufus R.         | 734312 |   65   |   48   |    0   |   68   |   45   |  45.20  |   F   |
| Smart, Maxwell            | 865868 |   55   |   64   |   99   |   99   |   79   |  79.20  |   C+  |
| Bond, James               | 700007 |   85   |   86   |   90   |   95   |   85   |  88.20  |   B+  |
| Student, Good             | 579301 |  100   |   98   |  100   |   95   |   99   |  98.40  |   A   |
| Smith, John               | 571894 |   85   |   73   |   89   |   85   |   87   |  83.80  |   B   |
| Doe, Jane                 | 690112 |   93   |   87   |   73   |   74   |   81   |  81.60  |   B-  |
| Dropout, College          | 735347 |   54   |    0   |   67   |    0   |    0   |  24.20  |   W   |
| Student, Solid Solid Soli | 536267 |   95   |   93   |   87   |   94   |   96   |  93.00  |   A   |
| Student, Perfect          | 511111 |  100   |  100   |  100   |  100   |  100   | 100.00  |   A   |
| Zappa, Zelda              | 999999 |   87   |   88   |   89   |   90   |   89   |  88.60  |   B+  |
| Abba, Abby A. A.          | 500000 |    1   |    2   |    3   |    4   |    5   |   3.00  |   F   |
+---------------------------+--------+--------+--------+--------+--------+--------+---------+-------+
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>



#define ARRAY_MAX_SIZE 100  // Max num of records in the array
#define LINE_MAX_LEN   256  // Max length of an input line
#define NAME_MAX_LEN    25  // Max num of char's in a name

typedef struct
{
	char name[NAME_MAX_LEN+1];
	int id;
	int test[2];
	int proj[3];
	float average;
	char grade[3];
} STUDREC;

int readRecords(STUDREC records[], int maxrecs, FILE* fp);
void printRecords(STUDREC records[], int count);
int showMenuGetChoice( STUDREC records[], int count );

//               0123456789012345678901234567//
#define GRADING "A+A A-B+B B-C+C C-D+D D-F W "
int getStartIndex( double avg )
{
    if( avg >= 95 ) return 0; // A+ // adjust all to your scale
    if( avg >= 90 ) return 2; // A
    if( avg >= 85 ) return 4; // A-
    if( avg >= 80 ) return 6;
    if( avg >= 75 ) return 8; // B
    if( avg >= 70 ) return 10;
    if( avg >= 65 ) return 12; // C +
    if( avg >= 60 ) return 14; // C
    if( avg >= 55 ) return 16; // C-
    if( avg >= 50 ) return 18;
    if( avg >= 45 ) return 20; // D
    if( avg >= 40 ) return 22;
    return 24;  // F
    
    // if 4th and 5th marks = 0 ... grade is W ithdraw
}

void printBad( char* p )
{
    int i, sum = 0, countGood = 0;
    char grade[3];
    double avg;

    // we are looking for upto (1+5) integers ...
    // first get/show id ...
    printf("id:");
    while( isdigit(*p) ) { putchar(*p), ++p; }
    printf(",  scores:"); // print : before field ...

    for( i = 0; i < 5; ++i )
    {
        int tmp;
        char* q = p; // id
        while( *p == ' ' ) ++p; // skip ws ...
        while( isdigit(*p) ) { putchar(*p); ++p; }
        putchar(':'); // print : after each field
        tmp = atoi( q );
        if( 0 <= tmp && tmp <= 125 )
        {
            sum += tmp;
            ++countGood;
        if( countGood == 0 ) countGood = 1; // and not divide by zero
        }
    }

    // now get and print grade ... ignore 'W' here
    
    avg = (double)sum / countGood; // adjust formula if needed
    i = getStartIndex( avg );

    strncpy( grade, &GRADING[i], 2 );
    grade[2] = '\0';
    printf( "%s\n", grade );
}


#define DATA_FILE "studentData.txt"
        
int main(int argc, char* argv[])
{
	FILE* fp = fopen( DATA_FILE, "r" );      // Pointer to the input file
	int count=0;   // Number of records read into the array.
	STUDREC records[ARRAY_MAX_SIZE];
/*
	// Open the file for read and print an error message and exit if that fails.
	if( argc > 1 ) fp = fopen( argv[1], "r");
	if( fp == 0 )
	{
		printf("\nError: Could not open file student_data for read.\n\n");
		getchar();
		return(1);
	}
*/
	count = readRecords( records, ARRAY_MAX_SIZE, fp );

	if( count == 0 )
	{
		printf("\nThere were 0 valid records found in file student_data.\n\n");
		printf( "\nPress 'Enter' to Exit ... " );
		getchar();
		return(2);
	}

	//printRecords(records, count);
	showMenuGetChoice( records, count );

	printf( "\nPress 'Enter' to continue ... " );
	while( getchar() != '\n' ) ;
	getchar();

	return(0);
} // main

 int readRecords(STUDREC records[], int maxrecs, FILE* fp)
{
	char line[LINE_MAX_LEN];
	int rc;
	int i = 0, j;

    // RECALL!!! fgets LEAVES '\n' char on end of line ... if it
    // was in the file at end of line and there's room in max line
	while( i < ARRAY_MAX_SIZE &&
            fgets(line, LINE_MAX_LEN, fp) != NULL )
	{
        int len, sum;
        char *p = line, *q, *pId;

        while( *p == ' ' ) ++p; // skip leading whitespace
        if( *p == 0 || *p == '\n' )
            continue; // blank line ...

        q = p;
        while( *q != 0 && !isdigit(*q) ) ++q;
        if( *q == '\0' )
        {
		    printf( "Invalid Record: ID, Bad: " ); printBad( q );
            continue;
        }

        pId = q; // line; // id on ...

        while( *(--q) == ' ' ) ; // backup ...
        ++q; // move forward one passed end

        len = q - p;
        if( len <= NAME_MAX_LEN )
        {
            strncpy( records[i].name, p, len );
            records[i].name[len] = '\0';
        }
        else
        {
		    printf( "Invalid Record: Student, Withnamethatistoolong: " ); printBad( pId );
            continue;
        }

        // parse rest of line ... // id + 5 more ints
		rc = sscanf( q, "%d%d%d%d%d%d",
			         &records[i].id,
                     &records[i].test[0], &records[i].test[1],
                     &records[i].proj[0], &records[i].proj[1],
                     &records[i].proj[2] ) ;


        if(records[i].id < 500000 || records[i].id > 999999)
        {
            printf( "Invalid Record: ID, Bad: " ); printBad( pId );
            continue;
        }

        if( records[i].test[0] > 125 || records[i].test[1] < 0 ||
            records[i].test[1] > 125 || records[i].proj[1] < 0 ||
            records[i].proj[1] > 125 || records[i].proj[2] < 0 ||
            records[i].proj[2] > 125 )
        {
            printf( "Invalid Record: Score, Bad: " ); printBad( pId );
            continue;
        }

        if( rc!=6 )
        {
            printf( "Invalid Record: Data, Missing: "); printBad( pId );
             continue;
        }

         // OK... GOOD DATA ... SO calculate ...
        // average and grade ...
        sum = 0;
        for( j = 0; j<5; ++j)
            sum += records[i].test[j];
        records[i].average = sum/5.0;

        // get start index in GRADING string
        j = getStartIndex( records[i].average ) ;
        
        strncpy( records[i].grade, &GRADING[j], 2 );
        if( records[i].test[4] == 0 && records[i].test[3 ] == 0 )
        strncpy( records[i].grade, &GRADING[26], 2 );
        records[i].grade[2] = '\0';
        
        i++;
	}
	
	return i ;
}

void printRecords(STUDREC records[], int count)
{
/*
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
	printf("\n| Student Name        | ID     | Test 1 | Test 2 | Proj 1 | Proj 2 | Proj 3 | Average | Grade |\n");
	printf("\n+---------------------+--------+--------+--------+--------+--------+--------+---------+-------+\n");
*/

    char formatStr[] =
    "\nName    :  %s\n"
    "ID      :  %d\n"
    "Test 1  :  %3d,   "
    "Test 2  :  %3d\n"
    "Proj 1  :  %3d,   "
    "Proj 2  :  %3d,   "
    "Proj 3  :  %3d\n"
    "Average :  %6.2f "
    "Grade   :  %s\n";

	int i = 0;
	for ( i = 0; i < count; i++ )
	{
	printf( formatStr,
			records[i].name, records[i].id,
            records[i].test[0],	records[i].test[1],
            records[i].proj[0], records[i].proj[1],
            records[i].proj[2], records[i].average,
            records[i].grade);
	}
	return;
} //printRecords

int showMenuGetChoice( STUDREC records[], int count )
{
  int c = -1;
  while( c != 6 )
  {
     printf("\nThere are %d records available.\n\n", count );
     printf("The jobs available are ...\n");
     printf("   1 Sort the records by the Student Name field.\n");
     printf("   2 Sort the records by the Student ID field.\n");
     printf("   3 Print a report of the records.\n");
     printf("   4 Search for a record by Student Name and print the record.\n");
     printf("   5 Search for a record by Student ID and print the record.\n");
	 printf("   6 Quit\n");
	 printf("Enter number (1..6) of job to perform: ");
	 fflush( stdin );

	 c = -1;
     scanf( "%d", &c );

     switch( c )
	 {
	 case 3  : printRecords(records, count); break;
	 case 6  : puts( "\n Exiting program now ..." ); return 0;
	 default : printf( "\nEnter a number of what you want to do ...  " );
	 }
  }
  return c;
}
Attached File  studentData.txt (1.33K)
Number of downloads: 89
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1