Hi All,
Thanks for all your help and advise. Here is a code for printing sales record. I don't understand what is the error in this code. When I try to complie and run, it says it cannot open the "sper.dat" file. Please help. Here is the 2 input files
sales.dat file
943 BusterBurger 4650000.00 1432567.88
245 PetRocks 8130000.00 95679.10
Salesper.dat file
Johnsonbaugh Epp IL 98450.00 29324.18 # 127 812
Cheessare Cruz TX 102300.00 15671.90 # 245 943
The output should be
Sales report by salesperson:
Salesperson: Chessare
Sales coach: Cruz
Sales region: TX
Base salary and bonus: 102300.00 15671.90
2 Account(s):
Name: PetRocks
Id: 245
Projected: 8130000.00
Actual: 95679.10
Name: BusterBurger
Id: 943
Projected: 4650000.00
Actual: 1432567.88
Salesperson: Johnsonbaugh
Sales coach: Epp
Sales region: IL
Base salary and bonus: 98450.00 29324.18
2 Account(s):
Name: AceRecords
Id: 127
Projected: 6780000.00
Actual: 2762890.50
Name: TacosAndThings
Id: 812
Projected: 2345000.00
Actual: 1412987.50
Here is the code
/***** BEGIN sales.h *****/
/** structure member macros **/
#define MaxName (100) /* last name */
#define MaxReg (2) /* 2 character region code */
#define MaxYear (4) /* current year */
#define MaxAccs (100) /* maximum number of accounts */
/** array sizes **/
#define MaxSales (100)
#define MaxSalesPer (100)
/** input file names **/
#define SalesFile "sales.dat"
#define SalesPerFile "sper.dat"
/** miscellany **/
#define MaxBuffer (500) /* input buffer */
#define AccDel '#' /* delimits accounts from other fields */
typedef struct sales {
int accId; /* account id */
char accName[ MaxName + 1 ]; /* account name */
float act; /* actual sales */
float proj; /* projected sales */
} Sales;
typedef struct salesPer {
Sales* accs[ MaxAccs ]; /* accounts */
int accCnt; /* accounts count */
char name[ MaxName + 1 ]; /* salesperson */
char boss[ MaxName + 1 ]; /* supervisor */
char reg[ MaxReg + 1 ]; /* sales region */
float base; /* base salary */
float bonus; /* year to date */
} SalesPer;
/***** END sales.h *****/
/***** BEGIN sales.c *****/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/** arrays **/
Sales salesTbl[ MaxSales ]; /* sales by account */
Sales* salesPtr[ MaxSales ]; /* pointers to salesTbl */
SalesPer salesPerTbl[ MaxSalesPer ]; /* sales personnel */
SalesPer* salesPerPtr[ MaxSalesPer ]; /* pointers to salesPerTbl */
/** array counts **/
int salesCnt, salesPerCnt;
/** function declarations **/
void
readSales( const char* infile ),
readSalesPer( const char* infile ),
quicksort( void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ) ),
report( void );
void*
findPivot( const void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ) );
int
partition( void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ),
void* pivot ),
compAccId( const void* e1, const void* e2 ),
compName( const void* e1, const void* e2 );
FILE*
openOrExit( const char* file, const char* mode );
main()
{
/* read sales data and sort */
readSales( SalesFile );
quicksort( salesPtr,
salesCnt,
sizeof ( salesPtr[ 0 ] ),
compAccId );
/* read salesperson data and sort */
readSalesPer( SalesPerFile );
quicksort( salesPerPtr,
salesPerCnt,
sizeof ( salesPerPtr[ 0 ] ),
compName );
/* print sales report */
report();
return EXIT_SUCCESS;
}
/* Read data into array salesTbl and set SalesCnt */
void readSales( const char* infile )
{
FILE* fptr;
int i = 0;
char buffer[ MaxBuffer + 2 ]; /* input buffer */
fptr = openOrExit( infile, "rb" );
salesCnt = 0;
while ( fgets( buffer, MaxBuffer, fptr ) ) {
sscanf( buffer, "%d %s %f %f",
&salesTbl[ i ].accId,
salesTbl[ i ].accName,
&salesTbl[ i ].act,
&salesTbl[ i ].proj );
i++;
}
fclose( fptr );
salesCnt = i;
/* Set pointers in salesPtr to addresses of
* corresponding elements in salesTbl.
*/
for ( i = 0; i < salesCnt; i++ )
salesPtr[ i ] = &salesTbl[ i ];
}
/* Read data into array salesPerTbl and set SalesPerCnt */
void readSalesPer( const char* infile )
{
FILE *fptr;
int i = 0, j;
char* del;
char id[ MaxName + 1 ];
char buffer[ MaxBuffer + 2 ]; /* input buffer */
Sales temp, *tempPtr = &temp, **ret;
fptr = openOrExit( infile, "rb" );
salesPerCnt = 0;
while ( fgets( buffer, MaxBuffer, fptr ) ) {
/* Read basic fields. */
sscanf( buffer, "%s %s %s %f %f",
salesPerTbl[ i ].name,
salesPerTbl[ i ].boss,
salesPerTbl[ i ].reg,
&salesPerTbl[ i ].base,
&salesPerTbl[ i ].bonus );
/*** read account ids and set pointers to Sales structures ***/
salesPerTbl[ i ].accCnt = 0;
j = 0;
/* find accounts delimiter within buffer */
del = strrchr( buffer, AccDel );
del++;
while ( *del && sscanf( del, "%s", id ) != EOF ) {
tempPtr -> accId = atoi( id );
del += strlen( id ) + 1; /* move beyond current id */
/* Search for sales record by account id. */
if ( ret = bsearch( &tempPtr,
salesPtr,
salesCnt,
sizeof ( salesPtr[ 0 ] ),
compAccId ) ) {
salesPerTbl[ i ].accCnt++;
salesPerTbl[ i ].accs[ j++ ] = *ret;
}
}
i++;
}
fclose( fptr );
salesPerCnt = i;
/* Copy address of sales table entries
* into pointer array.
*/
for ( i = 0; i < salesPerCnt; i++ )
salesPerPtr[ i ] = &salesPerTbl[ i ];
}
/* Open file in specified mode, returning
* file pointer if successfull; otherwise,
* issue warning message and exit program.
*/
FILE *openOrExit( const char* file, const char* mode )
{
FILE *fptr;
if ( NULL == ( fptr = fopen( file, mode ) ) ) {
fprintf( stderr,
"!! Can't open %s in mode %s. Exiting. !!\n",
file, mode );
exit( EXIT_SUCCESS );
}
return fptr;
}
void quicksort( void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ) )
{
void* pivot;
int i;
/* If array not yet sorted:
* (1) find a pivot
* (2) partition into two subarrays, left and right
* (3) quicksort the left subarray
* (4) quicksort the right subarray
*/
if ( pivot = findPivot( array, count, size, comp ) ) {
i = partition( array, count, size, comp, pivot );
quicksort( array, i, size, comp );
quicksort( ( char* ) array + i * size, count - i, size, comp );
}
}
/* Return the larger of the first element and any
* other that differs from it. If all elements the
* same, return NULL.
*/
void* findPivot( const void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ) )
{
int i = 1, flag;
void* next;
while ( i < count ) {
next = ( char* ) array + i * size;
flag = comp( array, next );
if ( flag > 0 ) /* array[ 0 ] > array[ i ] */
return array;
else if ( flag < 0 ) /* array[ i ] > array[ 0 ] */
return next;
else /* array[ 0 ] == array[ i ] */
i++;
}
return NULL; /* all elements the same */
}
/* Partition an array into two subarrays, the first
* holding elements <= pivot and the second holding
* elements > pivot.
*/
int partition( void* array,
size_t count,
size_t size,
int ( *comp )( const void* e1, const void* e2 ),
void* pivot )
{
int left = 0, right = count - 1, n = count;
void* next;
char temp[ MaxBuffer ];
if ( size >= MaxBuffer ) {
fprintf( stderr,
"\n!! MaxBuffer too small. Exiting. !!\n\n" );
exit( EXIT_SUCCESS );
}
while ( left <= right ) {
/* Search from left to right for 1st element >= pivot. */
next = ( char* ) array + left * size;
while ( left < n && comp( next, pivot ) < 0 ) {
left++;
next = ( char* ) array + left * size;
}
/* Search from right to left for 1st element < pivot. */
next = ( char* ) array + right * size;
while ( right >= 0 && comp( next, pivot ) >= 0 ) {
right--;
next = ( char* ) array + right * size;
}
/* Swap current left and right elements to put them in
* relative order with respect to each other and pivot.
*/
if ( left < right ) {
char *p1 = ( char* ) array + left * size,
*p2 = ( char* ) array + right * size;
memcpy( temp, p1, size );
memcpy( p1, p2, size );
memcpy( p2, temp, size );
left++;
right--;
}
}
return left;
}
int compAccId( const void* e1, const void* e2 )
{
Sales
*t1 = *( ( Sales** ) e1 ),
*t2 = *( ( Sales** ) e2 );
return t1 -> accId - t2 -> accId;
}
int compName( const void* e1, const void* e2 )
{
SalesPer
*t1 = *( ( SalesPer** ) e1 ),
*t2 = *( ( SalesPer** ) e2 );
return strcmp( t1 -> name, t2 -> name );
}
void report( void )
{
int i, j;
printf( "\nSales report by salesperson:\n\n" );
for ( i = 0; i < salesPerCnt; i++ ) {
printf( "\n\tSalesperson: %s\n",
salesPerPtr[ i ] -> name );
printf( "\tSales coach: %s\n",
salesPerPtr[ i ] -> boss );
printf( "\tSales region: %s\n",
salesPerPtr[ i ] -> reg );
printf( "\tBase salary and bonus: %.2f %.2f\n",
salesPerPtr[ i ] -> base, salesPerPtr[ i ] -> bonus );
printf( "\t%d Account(s): \n",
salesPerPtr[ i ] -> accCnt );
for ( j = 0; j < salesPerPtr[ i ] -> accCnt; j++ ) {
printf( "\n" );
printf( "\t\tName: %s\n",
salesPerPtr[ i ] -> accs[ j ] -> accName );
printf( "\t\tId: %d\n",
salesPerPtr[ i ] -> accs[ j ] -> accId );
printf( "\t\tProjected: %.2f\n",
salesPerPtr[ i ] -> accs[ j ] -> proj );
printf( "\t\tActual: %.2f\n",
salesPerPtr[ i ] -> accs[ j ] -> act );
}
}
}
/***** END sales.c *****/