2016-12-26 3 views
1

У меня есть этот простой проект, в котором я должен создать 4 массива и ввести данные о сотрудниках, массивы: идентификатор сотрудника, их зарплата, сокращение зарплаты и чистая зарплата. Я также должен печатать среднюю зарплату, номер ID сотрудника с самой высокой зарплатой и идентификатор сотрудника с минимальным разрезом.Ввод буквы в массив чисел

Код работает нормально, за исключением случаев, когда я ввожу букву, тогда она просто выполняет всю программу в странном виде (без форматирования, случайных чисел).

Почему? Письмо преобразуется в целое число, верно? Что заставляет его перестать работать должным образом?

Кроме того, не могли бы вы взглянуть на стиль кодирования, который я использовал, и сказать мне, есть ли способ улучшить его?

#include <stdio.h> 

#define SIZE 100 

int main(void){ 
    int n; /*Number of employees*/ 
    float average; /*Average of the employee's salary*/ 
    int max; /*Highest salary*/ 
    int min; /*Minimum cut*/ 
    int i; 
    int employee_number = 1;; /*The number (index +1) of the employee*/ 
    float sum = 0; /*The sum of the employee's salary*/ 
    int num_highest; /*The number of the employee with the highest 
    salary*/ 
    int num_lowest; /*The number of the employee with the lowest cut*/ 




int id_number[SIZE]; /*Array to hold employee's IDs in*/ 
float salary[SIZE]; /*Array for employee's salaries*/ 
float cuts[SIZE]; /*Array for salary cuts*/ 
float net_salary[SIZE]; /*Net salary after cuts*/ 

printf("Enter the number of employees\t"); 
scanf("%i", &n); 

for(i = 0; i < n; i++){ 
    printf("Enter the ID of employee #%i\t", employee_number); 
    scanf("%i", &id_number[i]); 

    printf("Enter the salary of employee #%i\t", employee_number); 
    scanf("%f", &salary[i]); 


    printf("Enter the salary cut of employee #%i\t", employee_number); 
    scanf("%f", &cuts[i]); 


    employee_number++; 
} 


for(i = 0; i < n; i++){ 
    net_salary[i] = salary[i] - (salary[i] * cuts[i] * 1/100); 
} 

for(i = 0; i < n; i++){ 
    sum += net_salary[i]; 
} 

average = sum/(float)n; 
printf("The average salary is %.2f\n", average); 


max = net_salary[0]; 
min = cuts[0]; 

for(i = 0; i < n; i++){ 
    if(net_salary[i] > max){ 
     max = net_salary[i]; 
     num_highest = i; 
    } 
    if(cuts[i] <= min){ 
     min = cuts[i]; 
     num_lowest = i; 
    } 
} 


printf("Employee with ID # %i has the highest salary which is %i\n", id_number[num_highest], max); 

printf("Employee with ID # %i has the lowest cut of %i and a base salary of %.2f", id_number[num_lowest], min, salary[num_lowest]); 


} 
+1

'min' и 'max' должен быть' float', а их спецификаторы формата 'printf' изменены на'% f'. –

+0

Используя float, вы также делаете свой код уязвимым для ошибок округления, а именно: если сумма> ¤ 1,67M с точностью 0,01, то будет потеря точности. –

+0

@ Аннет Хаапала Я заметил точность потери, но я не знаю, как ее исправить? Что, если есть сокращение от «11.23», как я могу выразить это без использования float? – MichaelX

ответ

3

Вы должны проверить возвращаемое значение каждого вызова функции scanf.

Если это значение меньше, чем количество входных аргументов, которые функция должна получать от пользователя, то он потерпел неудачу, и вы должны позвонить ему снова.

+1

Было бы лучше, если бы я напечатал что-то вроде fgets (id_number, sizeof (id_number), stdin – MichaelX

+0

@MichaelX с 'fgets', было бы проще сбросить строку ввода * и снова спросить, если возвращаемое значение из' sscanf' неверно, чем очистить блокирующую «букву» от ввода. Но вы не можете вводить 'int' напрямую, как вы указываете выше комментарий.Она нужна' sscanf'. –

0

Письма: char или char* при использовании в качестве входных данных для многих функций C и C++. char обычно может выводиться на консоль как закодированная цифра ASCII или как целое значение.

char может быть отлит в int очень легко в C, потому что это фактически считается числовым значением. Например, A становится 41, а B становится 42.

+2

Значение, хранящееся в 'char 'не обязательно является кодировкой ASCII, которая зависит от реализации. –

+0

@DavidBowling True. Было бы правильнее сказать, что оно декодируется как ascii перед печатью в качестве символа на экране для некоторых функций? – Aaron3468

+1

Было бы правильнее скажем, что значение, хранящееся в 'char', является членом набора символов выполнения. Это _probably_ значение ASCII, но стандарт не требует его. Существуют и другие кодировки, такие как EBCDIC. u можете прочитать об этом в стандарте (ISO/IEC 9899: 2011 5.2.1). На кодировки цифр есть некоторые ограничения. –

2

С точки зрения стиля кодирования вы можете использовать struct для хранения информации о каждом сотруднике и создания такого массива employees[]. Это помогает лучше упорядочить ваш код и позволяет избежать использования отдельных массивов для хранения информации о сотрудниках.

struct может выглядеть следующим образом:

typedef struct { 
    int id_number; 
    float salary; 
    float cuts; 
    float net_salary; 
} employee_t; 

И тогда вы можете создать массив структур, как это:

employee_t employees[n]; /* n is number of employees */ 

Это также хорошо, чтобы проверить возвращение scanf().

Так вместо того, чтобы делать просто:

scanf("%i", &n); 

Будьте очень осторожны, и изменить это:

if (scanf("%i", &n) != 1) { 
    /*exit program if true */ 
} 

Я написал код, чтобы продемонстрировать эти пункты:

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

typedef struct { 
    int id_number; 
    float salary; 
    float cuts; 
    float net_salary; 
} employee_t; 

void get_number_employees(int *n); 
void get_user_input(employee_t employees[], int n, float *average); 
void print_results(employee_t employees[], int n, float average); 
int highest_salary(employee_t employees[], int n); 
int lowest_cut(employee_t employees[], int n); 

int 
main(void) { 
    int n; 
    float average; 

    get_number_employees(&n); 

    employee_t employees[n]; 

    get_user_input(employees, n, &average); 

    print_results(employees, n, average);; 

    return 0; 
} 

void 
get_number_employees(int *n) { 
    printf("Enter number of employees: "); 
    if (scanf("%d", n) != 1) { 
     printf("Invalid number.\n"); 
     exit(EXIT_FAILURE); 
    } 
} 

void 
print_results(employee_t employees[], int n, float average) { 
    int high_sal, low_cut; 

    high_sal = highest_salary(employees, n); 
    low_cut = lowest_cut(employees, n); 

    printf("The average salary is %f\n", average); 

    printf("Employee with ID # %d has the highest salary which is %f\n", 
      employees[high_sal].id_number, employees[high_sal].net_salary); 

    printf("Employee with ID # %d has the lowest cut of %f and a base salary of %f\n", 
      employees[low_cut].id_number, employees[low_cut].cuts, employees[low_cut].salary); 
} 

void 
get_user_input(employee_t employees[], int n, float *average) { 
    int i, employee_number = 1, sum = 0; 

    for (i = 0; i < n; i++) { 

     printf("Enter the ID of employee #%d: ", employee_number); 
     if (scanf("%d", &(employees[i].id_number)) != 1) { 
      printf("Invalid number.\n"); 
      exit(EXIT_FAILURE); 
     } 

     printf("Enter the salary of employee #%d: ", employee_number); 
     if (scanf("%f", &(employees[i].salary)) != 1) { 
      printf("Invalid salary.\n"); 
      exit(EXIT_FAILURE); 
     } 

     printf("Enter the salary cut of employee #%d: ", employee_number); 
     if (scanf("%f", &(employees[i].cuts)) != 1) { 
      printf("Invalid cuts.\n"); 
      exit(EXIT_FAILURE); 
     } 

     employees[i].net_salary = employees[i].salary - (employees[i].salary * employees[i].cuts * 1/100); 

     sum += employees[i].net_salary; 

     employee_number++; 
    } 

    *average = (1.0f * sum)/n; 
} 

int 
highest_salary(employee_t employees[], int n) { 
    float max; 
    int i, idx; 

    max = employees[0].net_salary; 
    for (i = 1; i < n; i++) { 
     if (employees[i].net_salary > max) { 
      max = employees[i].net_salary; 
      idx = i; 
     } 
    } 
    return idx; 
} 

int 
lowest_cut(employee_t employees[], int n) { 
    float min; 
    int i, idx; 

    min = employees[0].cuts; 
    for (i = 1; i < n; i++) { 
     if (employees[i].cuts < min) { 
      min = employees[i].cuts; 
      idx = i; 
     } 
    } 
    return idx; 
} 
+0

Незначительное: чтобы избежать «двойной» математики и просто используйте 'float', используйте' * average = (1.0f * sum)/n; '(add f). – chux

Смежные вопросы