Thread: Having a few issues with this...

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    12

    Having a few issues with this...

    Hello everyone. So I'm writing a payroll program now (or trying to anyway), and I'm having a few problems. I got a fair amount of it working okay and I'm now working on a sorting function to list struct members by last name. That's one of the things I'd like some input on, but I also have a bigger issue. It seems the program will run a few times and then start crashing. I don't even know where to start as far as figuring out the cause. Can anyone give me a hand with that before moving on to the sorting issue.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    
    struct xrec
    {
       char first[11];
       char last[11];
       char ssn[12];
       char gen;
       double rate,ttlhrs,regHrs,otHrs,regPay,otPay,ttlPay;
     }; 
     typedef struct xrec Employee;
     
     int displayMenu(void);
     void alphaEmpList(Employee a[], int n);
     void printEmployees(Employee a[], int n);
     void printSalary(Employee * a, int n);
     void computePay(Employee * a, int n);
     int empSearch(Employee * a, int n,char * t);
     
     int main()
     {
       Employee temp;
        Employee x[20];
        
        char tempSSN[12];
       int size=0;
        int d,com,i;
        FILE * infile;
    
    
        infile=fopen("empData.txt","r");
        if(infile==NULL)
        {
           printf("\nCould not open input file!\n"); exit(1);
        }
        
        while(fscanf(infile,"%10s %10s %c %11s  %lf %lf %lf",
        temp.first,temp.last,&temp.gen,temp.ssn,&temp.rate,&temp.regPay,&temp.regHrs)!=EOF)
        {  
           temp.first[10]='\0';
            temp.last[10]='\0';
           temp.ssn[11]='\0';
           x[size++]=temp;
        }
        fclose(infile);
       
        
        do{
            com=displayMenu();
             switch(com)
             {
                case 1 : alphaEmpList(x,size); break;
                
                case 2 : printEmployees(x,size); break;
                
                case 3 : printSalary(x,size); break;
                
                case 4 : break;
                
                case 5 : break;
    
    
               case 6 : printf("\nEmployee's Last Name: ");fflush(stdin);
                           gets(temp.last);fflush(stdin);
                            printf("\nEmployee's First Name: ");fflush(stdin);
                            gets(temp.first);fflush(stdin);
                            printf("\nEmployee's Gender (M or F):");
                            scanf("%c",&temp.gen);fflush(stdin);
                            printf("\nEmployee's SSN :");fflush(stdin);
                            gets(temp.ssn);fflush(stdin);
                            printf("\nEmployee's Pay Rate: ");
                            scanf("%lf",&temp.rate);fflush(stdin);
                            printf("\nEmployee's Weekly Regular Hours: ");
                            scanf("%lf",&temp.regHrs);fflush(stdin);
                            printf("\nEmployee's Scheduled Overtime Hours: ");
                            scanf("%lf",&temp.otHrs);fflush(stdin);
                            x[size++]=temp;
                            break;
                         
               case 7 :    printf("\nEnter Employee's SSN:");fflush(stdin);
                      gets(tempSSN);
                      d=empSearch(x,size,tempSSN);
                      if ( d < 0)
                        printf("\nEmployee Record Not Found!\n");
                      else
                      {
                        x[d]=x[--size];
                      } break;
                            
               case 8 : infile=fopen("empData.txt","w");
                        for(i=0 ; i < size ; i++)
                            fprintf(infile,"%10s    %10s    %c    %11s    %.2lf    %.2lf    %.2lf    %.2lf    %.2lf %.2lf\n",
                              x[i].last,x[i].first,x[i].gen,x[i].ssn,x[i].rate,x[i].regHrs,x[i].otHrs,x[i].regPay,x[i].otPay,x[i].ttlPay);
                            
                            fclose(infile);
                            printf("\nEmployee record(s) successfully updated!\n");
                            break;
             }
          }while (com != 8);
        
        
        system("pause");
       return 0;
        }
        
        
        /* Search for an employee */
        int empSearch(Employee * a, int n,char * t)
        {
           int i;
           for(i=0 ; i < n ; i++)
             if(strcmp(a[i].ssn,t)==0)
             return i;
             return -1;
             }
             
    
    
        
        int displayMenu(void)
        {  int c;
          printf("*******************************************\n");
          printf("* 1. List Employees by Last Name          *\n");
          printf("* 2. List Employees Plus Salary           *\n");
          printf("* 3. List Employees by Highest Salary     *\n");
          printf("* 4. List Employees With Overtime         *\n");
          printf("* 5. List Female Employees                *\n");
          printf("* 6. Add New Employee                     *\n");
          printf("* 7. Delete  Employee                     *\n");
          printf("* 8. Save and Quit                        *\n");
          printf("*******************************************\n");
          
          printf("\nChoose option from  above menu: ");
          
          scanf("%d",&c);
        return c;
        }
        
        /* Menu Option 1 - Alphabetize employees by last name */
        void alphaEmpList(Employee * a, int n)
    {
        Employee temp;
        int i,empSwap;
    
    
        empSwap = 1;
        while (empSwap) 
         {
            empSwap = 0;
            for (i = 0; i < n - 1; i++) 
              {
                if (strcmp(a[i].last, a[i+1].last) > 0) 
                    {
                    temp=a[i];
                    a[i]=a[i+1];
                    a[i+1]=temp;
                    empSwap = 1;
                }
            }
             printf("%-10s %10s    %c    %11s    %.2lf\n",a[i].last,a[i].first,a[i].gen,a[i].ssn,a[i].rate);
        }
    }
    
    
        
        /* Menu Option 2 - Display all employees */
       void printEmployees(Employee a[], int n)
       {
           int i;
           for(i=0 ; i < n ; i++)
             printf("%-10s %10s    %c    %11s    %.2lf\n",a[i].last,a[i].first,a[i].gen,a[i].ssn,a[i].rate);
    
    
        }
        
        
        /* Menu Option 3 - Display employee pay rates */
        void printSalary(Employee * a, int n)
        {
           int i;
           for(i=0 ; i < n ; i++)
             printf("%-10s    %10s's hourly pay rate: %.2lf\n",a[i].last,a[i].first,a[i].rate);
        }      
        
        
        
        /* Calculate employee pay for the week */
        void computePay(Employee * a, int n)
        {
           double total;
           int i;
            
            
           for(i=0; i < n ; i++)
           {
              a[i].regPay=a[i].rate * 40;
              a[i].otPay=(a[i].regPay * 1.5) * a[i].otHrs;
              a[i].ttlPay=a[i].regPay+a[i].otPay;
              
              printf("%10s, %10s's total pay for this week is %.2lf \n",a[i].last,a[i].first,a[i].ttlPay);
            }
       }
    The sort function I need help with is at around line 139 under /* Menu Option 1 - Alphabetize employees by last name */. Am I even close to the mark with it and where am I going wrong?
    Attached Files Attached Files

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It doesn't help that the format of your data file does not match the fscanf() format. There is extra data on each line, and fscanf() will not skip that data (when it reaches the end of what is intended to be read, the remaining data on a line will be picked up by the next call of fscanf()). If fscanf() encounters an error because of this, it will probably not return EOF. Odds are, because of this, the loop doing fscanf() is accessing more elements of the array x than you think it is - and if it goes past 20, that would explain the crashes.

    gets() is so unsafe - in terms of permitting overwriting random areas of memory if the user doesn't limit what s/he types - that it has been removed from the latest C standard. Use a safer function, such as fgets() [note the leading f].

    fflush() has undefined behaviour for any input stream. fflush(stdin) certainly does not discard pending input from stdin. Don't use it.

    If you want to sort, look up the qsort() function (declared in the standard header <stdlib.h>) in the first instance, rather than trying to roll your own.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Jan 2014
    Posts
    12
    Thanks for the reply, grumpy. Can you clarify what you mean by "the format of the data file". Do you literally mean a .txt file versus other format or the formatting within the file. If the former, then would .dat be better?

  4. #4
    Registered User
    Join Date
    Jan 2014
    Posts
    10
    Take a look at the .txt file that you supplied with your code. In your fscanf() statement you are reading in fewer values than what is contained on a single line of the txt file. In your fscanf() you are only reading in 7 items, where as the file contains 10 items. You are going to be running into an issue where fscanf() is going to read past where you are expecting, and thus your next call to fscanf will remain on the same line where it left off.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I mean the fact that each line of the data file contains (apart from whitespace) two strings, a char, another string, then six floating point values.

    The format string, OTOH, contains two strings, a char, another string, then THREE floating point values.

    fscanf() does not skip data, and commence or end at a newline.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,754
    You should only read the file with fgets, then parse the buffer using sscanf (for now).

    Code:
        char buff[BUFSIZ];
        while ( fgets(buff,BUFSIZ,infile) != NULL ) {
            if ( sscanf(buff,"%10s %10s %c %11s  %lf %lf %lf",
                    temp.first,temp.last,&temp.gen,temp.ssn,
                    &temp.rate,&temp.regPay,&temp.regHrs) == 7 ) {
               x[size++]=temp;
            } else {
               fprintf(stderr,"Cant parse %s\n", buff);
            }
        }
    This achieves a couple of things.
    1. Failure to parse a single line (either by messing up the expected conversion, or corrupted data) does not cause a ripple effect through the rest of the file.

    2. By using == rather than !=, you're making a positive assertion that the parse was OK.
    With a fscanf containing 7 conversions, then the possible return values are 0,1,2,3,4,5,6,7 and EOF. Only one of those counts as success, and all the others indicate varying levels of trouble.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2014
    Posts
    12
    Thanks everyone for the assistance. I'll work on what you've given me and update the thread afterward.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cpp issues
    By nime in forum C Programming
    Replies: 9
    Last Post: 09-27-2010, 07:44 AM
  2. Having issues with my FFT
    By DavidP in forum C++ Programming
    Replies: 8
    Last Post: 04-05-2010, 01:27 PM
  3. ASM w/ C++ issues
    By RobotGymnast in forum C++ Programming
    Replies: 17
    Last Post: 09-20-2008, 03:11 AM
  4. issues
    By Logan1033 in forum C Programming
    Replies: 12
    Last Post: 08-16-2006, 01:54 PM
  5. Issues
    By Tamandt in forum C++ Programming
    Replies: 22
    Last Post: 09-10-2004, 11:42 AM