Write a program that reads data from binary file EMPLOYEE.DAT (employees are proffesors and teaching assistants, assume that the file exists). Split data about proffesors and teaching assistants in two separate text files and sort data by ID using insertion sort algorithm. Search and print data about employee which ID is entered using linear search algorithm. Employee data: ID,NAME,SURNAME,TITLE,SALARY.

I need a clarification on what is wrong with functions for sorting and searching in the following code:

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

typedef struct
{
   char ID[20];
   char surname[20],name[20];
   char title[20];
   double salary;
}EMPLOYEE;

void printEmployeeToFile(EMPLOYEE empl,FILE *ptr_f,int ord_num)
{
  fprintf(ptr_f,"%2d. %-19s %-19s %-19s %-19s %6.2lf",
                ord_num,empl.ID,empl.name,empl.surname,empl.title,empl.salary);
}

void insertionSort(EMPLOYEE *arr)
{
    int i,j;
    EMPLOYEE x[1000];
    for(i=0; i != EOF; i++)
    {
       x=arr[i];
       for(j=i; j > 0; && x < arr[j-1]; j--)
           arr[j].ID = arr[j-1].ID;
       arr[j]=x;
    }
}

void split(FILE *empl_ptr,FILE *proffesors,FILE *teaching_assistants)
{
  char temp[100];
  int prof_ord_num=0,ta_ord_num=0;
  EMPLOYEE empl;
  while(fread(&empl,sizeof(EMPLOYEE),1,empl_ptr))
  {
    if(!strcmp(empl.title,"proffesor"))
        printEmployeeToFile(empl,proffesors,++prof_ord_num);
    else if(!strcmp(empl.title,"teaching assistant"))
        printEmployeeToFile(empl,teaching_assistants,++ta_ord_num);
  }
}

int linearSearch(EMPLOYEE *arr,char *key)
{
   int i=0;
   while(strcmp(arr[i].ID,key))
     i++;
   return i;
}

int main()
{
    FILE *empl_ptr,*proffesors,*teaching_assistants;
    EMPLOYEE *arr;
    EMPLOYEE empl;
    arr=(EMPLOYEE*)malloc(1000 * sizeof(EMPLOYEE));
    int i
    if((empl_ptr = fopen("EMPLOEE.DAT","rb")) && (proffesors = fopen("PROFFESORS.TXT","w")) &&
      (teaching_assistants = fopen("TEACHING_ASSISTANTS.TXT","w")))
    {
      insertionSort(arr);
      split(empl_ptr,proffesors,teaching_assistants);
      fclose(empl_ptr);
      fclose(proffesors);
      fclose(teaching_assistants);
    }
    printf("Enter ID for searching");
    scanf("%s",empl.ID);
    printf("Searching result:");
    i=linearSearch(arr,empl.ID);
    free(arr);
    return 0;
}

Edited 11 Months Ago by negru

You need to study what an insertion sort is. What are you inserting? How are you sorting the array? Also, your for loops in the sorting function is bogus. Didn't the compiler complain, at least about the inner loop? FWIW, EOF is dependent upon the context. Sometimes it means -1. Other times it means something else.

I think you need to go back to the drawing board and rethink this assignment.

There are several steps to the final solution of your problem ...

The first step that I would suggest you take would be to get some test data,
perhaps like this ... to get a bin file to test the rest of your code:

/* spiltInto2Files.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strcmp */

#define MAX_STR_LEN 19
#define FORMAT_STR_IN " %19s %19s %19s %19s %lf"
#define FORMAT_STR_OUT "%-19s %-19s %-19s %-19s %10.2f\n"


const char* START_TXT = "start.txt";
/*
12345 Samuels Joe Prof 60000
12348 Plummer Bob Assist 30000
12347 Anderson Kim Assist 25000
12344 Davidson George Prof 110000
12346 Bowers Ann Assist 20000
*/

const char* TEST_BIN = "test.bin";

const char* PROF_FILE   = "prof.txt";
const char* ASSIST_FILE = "assist.txt";


typedef struct
{
   char id[MAX_STR_LEN+1],
        surname[MAX_STR_LEN+1],
        name[MAX_STR_LEN+1],
        title[MAX_STR_LEN+1];
   double salary;

} Employee ;

int create_bin_file( const char* fname_in, const char* fname_out)
{
    FILE* fin  = fopen( fname_in, "r" );
    FILE* fout = fopen( fname_out, "wb" );
    if( fin && fout )
    {
        char buf[128];
        Employee tmp;
        while( fgets( buf, sizeof buf, fin ) )
        {
            if( sscanf( buf, FORMAT_STR_IN, tmp.id, tmp.surname, tmp.name, tmp.title, &tmp.salary ) != 5 )
                return 0;;
            /* size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); */
            if( fwrite( (char*)&tmp, sizeof(Employee), 1, fout ) != 1 )
                return 0;
        }
        fclose( fout );
        fclose( fin );
        return 1;
    }
    /* else */
    printf( "Error opening files ...\n" );
    return 0;
}

After that, you should test that the bin file was ok ...
perhaps by reading it back and splitting it,
as you read each record,
into the two files requested, one file for each of the 2 types of records.

int read_bin_file_split( const char* bin_file_in, const char* prof_file_out, const char* assist_file_out )
{
    FILE* fin  = fopen( bin_file_in, "rb" );
    FILE* fout_p = fopen( prof_file_out, "w" );
    FILE* fout_a = fopen( assist_file_out, "w" );
    if( fin && fout_p && fout_a )
    {
        Employee emp;
        /* size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); */
        while( fread( &emp, sizeof(Employee), 1, fin ) )
        {
            if( strcmp( emp.title, "Prof" ) == 0 )
            {
                fprintf( fout_p, FORMAT_STR_OUT,
                         emp.id, emp.name, emp.surname, emp.title, emp.salary );
            }
            else
            {
                fprintf( fout_a, FORMAT_STR_OUT,
                         emp.id, emp.name, emp.surname, emp.title, emp.salary );
            }
        }
        fclose( fout_a );
        fclose( fout_p );
        fclose( fin );
        return 1;
    }
    /* else */
    printf( "Error opening files ...\n" );
    return 0;
}

Then ... it would be good to test that each of those files are ok, probably by reading them into a dynamic array of the right size, maybe like this:

Employee* read( const char* fname, int* size )
{
    FILE* fin = fopen( fname, "r" );
    if( fin )
    {
        char buf[128];
        int i = 0;
        Employee* emp;

        *size = 0;
        while( fgets( buf, sizeof buf, fin ) )
            ++ *size;
        /* printf( "*size = %d\n", *size ); */

        rewind( fin );

        emp = malloc( *size * sizeof(Employee) );
        if( emp )
        {
            while( fgets( buf, sizeof buf, fin ) )
            {
                if( sscanf( buf, " %s %s %s %s %lf", emp[i].id, emp[i].surname, emp[i].name, emp[i].title, &emp[i].salary ) == 5 )
                {
                    ++i;
                }
                else
                {
                    printf( "Unexpected read error ... quitting now ...\n" );
                    break;
                }
            }

            fclose( fin );

            if( *size == i )
                return emp; /* flag 'good' value */
            /* else .. */
            free( emp );
            printf( "Unexpected error ... WHOLE file NOT read .. quitting now ...\n" );
            return 0;
        }
    }
    printf( "There was a problem opening file %s\n", fname );
    return 0; /* flag 'bad' value */
}

Then, if you wish to have the files in sorted order, you could handle that with 2 more functions ... like this:

int save( const char* fname, const Employee* emp, int size )
{
    FILE* fout = fopen( fname, "w" );
    if( fout )
    {
        int i;
        for( i = 0; i < size; ++ i )
        {
            fprintf( fout, FORMAT_STR_OUT,
                     emp[i].id, emp[i].name, emp[i].surname, emp[i].title, emp[i].salary );
        }
        fclose( fout );
        return 1; /* flag 'good' value */
    }
    printf( "There was a problem opening file %s\n", fname );
    return 0; /* flag 'bad' value */

}

/* sort by Enployee id's ... */
void isort( Employee* ary, int size )
{
    int i;
    for( i = 1; i < size; ++i ) /* start with an array of just the first 2 elements (if exists) */
    {
        Employee cmp = ary[i]; /* get copy of this new cmp element on each outer loop */
        int j = i-1; /* get index of element just to the left of the above 'cmp' to start comparisons */
        while( j >= 0 && cmp.id < ary[j].id )
        {
            ary[j+1] = ary[j]; /* copy element 'up' */
            --j; /* decrement j in preparation for next inner loop */
        }
        ary[j+1] = cmp; /* insert element at index j+1 (since j was decremented above) */
    }
}

But you could test this out in steps, if you keep adding code ... in a little (top-down) test program in the main function ... something like this:

int main()
{
    if( create_bin_file( START_TXT, TEST_BIN ) )
    {
        if( read_bin_file_split( TEST_BIN, PROF_FILE, ASSIST_FILE ) )
        {
            int size;
            Employee * emp;
            if( (emp= read( PROF_FILE, &size )) )
            {
                int i;
                isort( emp, size );
                for( i = 0; i < size; ++ i )
                {
                    printf( "%s %s %s %s %f\n",
                            emp[i].id, emp[i].name, emp[i].surname, emp[i].title, emp[i].salary );
                }

                if( !save( PROF_FILE, emp, size ) )
                {
                    printf( "There was problem savimg the sorted file %s\n", PROF_FILE );
                }

                free( emp );
            }

            putchar( '\n' );
            if( (emp= read( ASSIST_FILE, &size )) )
            {
                int i;
                isort( emp, size );
                for( i = 0; i < size; ++ i )
                {
                    printf( "%s %s %s %s %f\n",
                            emp[i].id, emp[i].name, emp[i].surname, emp[i].title, emp[i].salary );
                }

                if( !save( ASSIST_FILE, emp, size ) )
                {
                    printf( "There was problem savimg the sorted file %s\n", ASSIST_FILE );
                }

                free( emp );
            }
        }
    }

    printf( "\nPress 'Enter' to contimue/exit ... " );
    fflush( stdout );
    getchar();
    return 0;
}

I hope that these snippets of code do give you several ideas about how to attack a multi-part coding problem in steps ...

If you will learn to code in steps ...
and to test your running code at each step,
programming can actually become fun ...
i.e. if you enjoy problem solving,
even the challenge of sometimes solving fairly big and quite complex problems.

You still have more to do ... but the examples here could give you a good start.

Edited 11 Months Ago by David W

This question has already been answered. Start a new discussion instead.