/* Program to locate employees paid more than a user-supplied threshold. Input: the name of the file with the employee data, and the threshold amount. The file must contain names in the first 30 columns, then the salary as a float. A final line containing only a '#' marks the end of the file. */ #include #include #define TRUE (1) #define FALSE (0) /* Declaration for functions called in main: */ FILE * file_open(char name[], char access_mode[]); void process_file(FILE * fin, float threshold); main() { FILE * fin; /* Declare the FILE pointer (1). */ char filename[81]; float threshold; /* Ask the user the name of the file with the data. */ printf("Name of file to read? "); scanf("%80s", filename); /* Open the file (using our own function - see below) (2). */ fin = file_open(filename, "r"); /* Ask the user the salary threshold limit. */ printf("Salary threshold amount? "); scanf("%f", &threshold); /* Read all the file data, displaying those above the threshold (3). */ process_file(fin, threshold); /* Close the file (4). */ fclose(fin); return 0; } /******* file_open ******* Works like fopen, but checks for errors, and if so, stops with an error message. */ FILE * file_open(char name[], char access_mode[]) { FILE * f; f = fopen(name, access_mode); if (f == NULL) { /* error? */ /* Library function perror prints an informative message. */ perror("Cannot open file"); exit(EXIT_FAILURE); /* Terminate after printing error message. */ } return f; /* Only happens if fopen succeeded. */ } /******* process_file ******* On entry: fin refers to a file opened for input. It must contain names and salaries. The name must occupy the first 30 chars of the line. The last line starts with '#'. On exit: Will have listed all lines with salary greater than the threshold. Prints a heading before the first such line, or an informative message if none are found. No error checking is done. */ #define NAME_SIZE (30) void process_file(FILE * fin, float threshold) { int no_previous_listings = TRUE; /* Used to decide when to print the heading etc. */ char employee_name[NAME_SIZE + 1]; float salary; /* Load the first name */ fgets(employee_name, NAME_SIZE+1, fin); while (employee_name[0] != '#') { /* does not start with "#" */ /* Load salary and following character (to skip the '\n') */ fscanf(fin, "%f%*c", &salary); /* Decide whether to print. */ if (salary>threshold) { if (no_previous_listings) { /* Do we need headings? */ printf("Staff with salary over $%4.2f:\n", threshold); printf( "Name%*sSalary\n====%*s======\n", NAME_SIZE-4, " ", NAME_SIZE-4, " " ); no_previous_listings = FALSE; } printf("%*s$%4.2f\n", NAME_SIZE, employee_name, salary); } /* Load the next name */ fgets(employee_name, NAME_SIZE+1, fin); } /* Check whether anything was printed. */ if (no_previous_listings) { printf("No staff have salaries over $%4.2f\n", threshold); } }