员工支付滚动信息并将其放入数组

时间:2016-09-13 21:09:09

标签: c

我的程序需要接受人们的输入并计算工资并扣留并打印出所有内容。我有打印输出,但我在将其存储在阵列中时遇到了麻烦。

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

typedef char *string;

#define MaxEmployees 100

typedef struct {
    string name;
    string title;
    string ssnum;
    double salary;
    int withholding;
} employeeRecordT;

typedef struct {
    string name;
    string title;
    string ssnum;
    double salary;
    int withholding;
} *employeeT;

输入:payrollT

此类型代表整个员工集合。类型定义使用employeeT值的动态数组,以确保该类型不存在最大限制。这种设计的代价是程序员必须使用NewArray明确地为数组分配存储空间。

typedef struct {
    int nEmployees;
    employeeT *employees;
} *payrollT;

全局变量

staff       -- Array of employees  
nEmployees  -- Number of employees  
manager     -- Used to produce a figure for the code
static employeeT staff[MaxEmployees];
static int nEmployees;

static employeeRecordT manager = {
    "Ebenezer Scrooge", "Partner", "271-82-8183", 250.00, 1
};

私人功能声明:

 static void InitEmployeeTable(void);
 static payrollT CreatePayroll(employeeT staff[], int nEmployees);
 static void ListEmployees(payrollT payroll);
 static double AverageSalary(payrollT payroll);
 static void  WeeklyPayroll(payrollT payroll);
 //static void GetPayroll(void);
 static double ssnum(payrollT payroll);

主程序:

int main(void)
{
    payrollT payroll;
    //GetPayroll(payroll);
    InitEmployeeTable();
    payroll = CreatePayroll(staff, nEmployees);
    ListEmployees(payroll);
    WeeklyPayroll(payroll);
}

static void InitEmployeeTable(void)
{
    employeeT empRec;
    int condition = 1;
    int emp_id = 2;
    empRec = (employeeT)malloc(sizeof (employeeT));
    empRec->name = "Ebenezer Scrooge";
    empRec->title = "Partner";
    empRec->ssnum = "271-82-8183";
    empRec->salary = 250.00;
    empRec->withholding = 1;
    staff[0] = empRec;
    empRec->name = "Bob Cratchit";
    empRec->title = "Clerk";
    empRec->ssnum = "314-15-9265";
    empRec->salary = 15.00;
    empRec->withholding = 7;
    staff[1] = empRec;
    nEmployees = 2;

    do {
        //malloc(sizeof ());
        char name;
        char title;
        char ssnum;
        float salary;
        double withholding;
        printf("enter name or input stop to quit!\n");
        printf("enter first and last name\n");
        scanf("%s", empRec->name);
        //empRec->name = name;
        printf("\nenter title\n");
        scanf("%s", empRec->title);
        //empRec->title = title;
        printf("\nenter social xxx-xx-xxxx\n");
        scanf("%s", empRec->ssnum);
        //empRec->ssnum = ssnum;
        printf("\nenter salary xx.xx\n");
        scanf("%lf", &empRec->salary);
        //empRec->salary = salary;
        printf("\nenter withhodling x\n");
        scanf("%d", &empRec->withholding);
        //empRec.withholding = withholding;
        printf("printed %d", emp_id++);
        staff[emp_id] = empRec;
        emp_id++;
        if (strcmp(empRec->name,"stop") == 1) {
            condition = 0;
            break;
        }
        //staff[emp_id]=empRec;
        //emp_id++;
    } while (condition = 1);

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您没有为任何字符串分配存储空间(nametitlessnum [在您的记录中,现在我看起来也在你的do-while循环中 - 你不能使用char name;,你需要例如char name[100];或指针malloc])。使用typedef string隐藏了这一事实。您可以分配给字符串变量并为您分配的分配的唯一时间是在声明时,因为大小在编译时已知,例如:

char *str = "Hello";
char *str2 = { 'w', 'o', 'r', 'l', 'd', '\0' };

在您的情况下,manager的字符串分配很好,因为它们位于初始值设定项中,但您仍需要为employeeRecordT中的字符数组提供明确的大小。

您需要做的是为这些字符数组提供明确的大小,或者为它们显式分配存储空间(malloc等);而不是分配,您必须使用strcpy()<string.h>)(或strncpy(),以防出现溢出)。

你可以为你的title变量做一些事情来保存空间是为了声明一个静态分配的字符串列表,然后让title成为指向列表中相应元素的指针,例如(const是可选的,但只是确保这个数组不会以任何方式搞乱):

const char const *titles[] = { "Partner", "Clerk", "etc." };

typedef struct {
    const char *title;
    // ...
} *employeeT;

// ...
empRec->title = titles[0];    // Points title to "Partner"

您甚至可以使用enum来帮助索引(所有其余代码都是相同的):

enum { PARTNER, CLERK, ETC };
// ...
empRec->title = titles[CLERK];    // Points title to "Clerk"

您的代码的另一个问题是您只为单个employeeT记录分配存储空间;如果不再次调用empRec,则无法重复使用malloc()。将要发生的事情是,每次更改empRec时,它都会更改所有以前的staff元素,因为它们都指向同一位置(即staff[0]将包含确切的内容你将staff[1]设置为)。 另一个问题是你正在使用sizeof (employeeT),但这是错误的,因为这只是给你结构的指针的大小。这是typedef s使事情更加混乱的一个原因。您应该创建您的结构(并且如果需要,也可以键入def),但是当您需要指向它时,您应该诚实地在代码中使用'*'(可选地创建 second typedef,即typedef struct { // ... } node; typedef node *node_ptr;或甚至同时:typedef struct { // ... } node, *node_ptr;)。您有两个选项,在开始为其成员分配第二(及后续)时间之前,您可以再次为malloc()调用empRec,或者您可以简单地丢弃empRec变量并使用{直接{1}},例如:

staff

以后staff[0] = malloc(sizeof *staff[0]); // Note I couldn't use employeeT above since you need struct size, not ptr. // (`sizeof (employeeRecordT)` could have been used though) strcpy(staff[0]->name, "Ebenezer Scrooge"); // ... staff[0]->salary = 250.00; // ... <{1}}

此外,我不明白为什么你有这个free()类型,它本质上是你的staff[]数组的副本?如果你想要payrollT,你可以只有一个指向员工记录的指针(顺便提一下,你可能不想要staff,你可能想要payrollT(因为它已经是指针类型)或employeeT *employees;)。我认为这是我在程序片段中看到的另一个错误。

如果你愿意,你可以摆脱你的employeeT employees;变量,而不是使用do-while循环,只需在你的{{employeeRecordT *employeescondition中使用while (1) 1}}会为你退出。这样您就可以确定它至少仍然被评估过一次。

顺便说一句,您不必转换break的返回值。这是不必要的,因为void指针安全地自动升级到任何其他类型(反之亦然)。有关详细信息,请参阅here。另外,我看到你提到if但从未在任何地方引用它。