SK said:
for (n = 0; n < EMPLOYEES; ++n){
do{
printf("\nEnter employee # %d: ", count_EMP);
You have not ended this printf output with a "\n". Thus, its content
might not be output on some systems until the next occurrence of a \n
which happens in your next printf.
scanf("%s %s", &fn, &ln);
This is a "buffer overflow". It means that a user can input data
sufficient to cause a write memory beyond the bounds which you've
declared -- this has undefined behavior in the C language.
The standard half assed solution here is to do a fgets() to just read
the raw line, then an sscanf() to parse out the parameters. However,
that suffers the (lesser) problem of buffer truncation. If you are
intent on using the primitive C library, then I would recommend you look
at my article on user input here:
http://www.pobox.com/~qed/userInput.html
You can just use the getf.zip sources directly and then use
getstralloc() macro to fetch the user input correctly, then use sscanf
(after possibly using malloc to allocate space for your inputs).
But if you find all this just a little too painful, you can instead use
"The Better String Library" (
http://bstring.sf.net/). You would just do
a bgets(), then a bsplit() to get all the names from the input.
printf("\nPlease enter the hourly wage for the employee: ");
scanf("%f", &wage);
printf("\nPlease enter the number of hours worked this"
" week: ");
scanf("%f", &hours);
Those, of course, are *not* buffer overflows because of the naturally
compressing nature of these modes of usage of scanf.
printf("\nThank you. Process another employee?");
scanf("%s", &again);
You only want to read one character here. So first of all you are
buffer overflowing again, but you are also probably using the wrong
scanf mode. You mean "%c" here, not "%s".
}while(again == 'Y' || again == 'y');
Wait -- you've written a loop here, but you are not storing your data
into incremental storage of any kind. You need to move this do { ... }
while() to the outer loop.
/*Read in the input*/
numemp = scanf("%11s%11s%f%f%f%f%f", &fn, &ln, &RegHr,
&wage, &OTHr, &OTHrPay, &GrossPay);
So is this redundant, or what are you trying to do here? In any event,
this has the buffer truncation problem. If you enter a name with more
than 11 characters, then the spill over characters will just bleed into
the successive parameters.
/*Check if user is done*/
if(again != 'Y' && again !='y');
printf("End of processing\n\n\n");
/*Process the input*/
if(numemp == 6)
{
if (RegHr > 40)
{
OTHr = hours - 40;
OTHrPay = OT * OTHr * wage;
Ok, here you are overwriting OTHr and OTHrPay with these computations,
after you were trying to read them as input. So you are essentially
just losing your input. So perhaps your second scanf is completely
superfluous and should just be removed. (You still need to move the do
{ ... } while to the outer loop.)
RegHrPay = 40.0 * wage;
}
else
{
RegHrPay = hours * wage;
OTHrPay = 0.0;
}
GrossPay = RegHrPay + OTHrPay;
strncpy(emp[n].first_name, fn, FULLNAME);
strncpy has a well known design flaw, where a maximal truncation doesn't
add a '\0' on the end. In general, I would avoid strncpy() in all
cases. There is another extension out there called "strlcpy" which does
not suffer this problem, but still leaves you with the buffer truncation
weakness.
"The Better String Library" makes this whole thing a non-issue. You
would just use bstrcpy(), and there would not be any truncation or
overflow issues.
emp[n].first_name[FULLNAME] = '\0';
This is a bounds overrun error. An array declared of length n can be
legally indexed from 0 to n-1 inclusive. So FULLNAME is 1 more than the
limit you can index with for this declared array. That said, it will
likely function, but end up setting a '\0' into the first character of
the next element (in this case .last_name, thus causing people's last
names to be empty).