所以,我们刚刚开始在我的在线课程中学习链接列表和数据结构,但我一直在努力解决这个问题。我对指针有一个大致的了解但是当你把所有东西组合在一起时,我会完全迷失方向。
因此对于这个程序,我应该处理员工数据并通过使用结构和指针来访问它。但是,我认为我没有将正确的值传递给函数,因为数据没有保存,我无法访问它。任何帮助将不胜感激。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct address {
char street[49];
char city[29];
char state[2];
char zip[5];
};
struct data{
char name[39];
struct address addy;
float salary;
struct data *next;
} emp;
void LIST(struct data* head);
void INSERT(struct data* head, char* name, struct address addr, float salary);
void DELETE(char* name, struct data* head);
void EDIT(struct data* head, char* name, struct address addr, float salary);
void CALCPAYROLL(struct data* head);
void HELP();
int main()
{
char input[15];
int quitter = 1;
struct data *head = NULL;
head = malloc(sizeof(emp));
if (head == NULL){
return 1;
}
while(quitter == 1)
{
printf(" enter command: \n");
fgets(input,15, stdin);
input[strlen(input) -1] = '\0';
if((strcmp(input, "List") == 0) || (strcmp(input, "list") == 0))
{
LIST(head);
}
if((strcmp(input, "Insert") == 0) || (strcmp(input, "insert") == 0))
{
scanf("%s-%s-%s-%s-%s-%f", head->name, head->addy.street, head->addy.city, head->addy.state, head->addy.zip, &head->salary);
INSERT(head, head->name, head->addy, head->salary);
}
if ((strcmp(input, "Delete") == 0) || (strcmp(input, "delete") == 0))
{
DELETE(head->name, head);
}
if ((strcmp(input, "Edit") == 0) || (strcmp(input, "edit") == 0))
{
EDIT(head, head->name, head->addy, head->salary);
}
if ((strcmp(input, "Payroll") == 0) || (strcmp(input, "payroll") == 0))
{
CALCPAYROLL(head);
}
if ((strcmp(input, "Help") == 0) || (strcmp(input, "help") == 0))
{
HELP();
}
if ((strcmp(input, "Quit") == 0) || (strcmp(input, "quit") == 0))
{
printf("============\nGood bye!\n");
quitter = 0;
}
}
return 0;
}
void LIST(struct data* head)
{
struct data* temp = head;
while (temp) {
printf("%s\n%s\n%s, %2s %5s\n%9.2f\n-----\n", temp->name, temp->addy.street, temp->addy.city, temp->addy.state, temp->addy.zip, temp->salary);
temp = temp->next;
printf("%s\n%s\n%s, %2s %5s\n%9.2f\n-----\n", temp->name, temp->addy.street, temp->addy.city, temp->addy.state, temp->addy.zip, temp->salary);
temp = temp->next;
}
}
void INSERT(struct data* head, char* name, struct address addr, float salary)
{
struct data* newEmployee = NULL;
newEmployee = (struct data*)malloc(sizeof(emp));
strcpy(newEmployee->name, head->name);
newEmployee->salary = head->salary;
strcpy(newEmployee->addy.street, head->addy.street);
strcpy(newEmployee->addy.city, head->addy.city);
strcpy(newEmployee->addy.state, head->addy.state);
strcpy(newEmployee->addy.zip, head->addy.zip);
struct data* temp = head;
while(temp->next && temp->next->name > newEmployee->name)
{
temp = temp->next;
}
newEmployee->next = temp->next;
temp->next = newEmployee;
}
void DELETE(char* name, struct data* head)
{
char del[39];
scanf("%39s", del);
struct data * toBeDeleted = NULL;
struct data * temp = head;
while (strcmp(del, temp->name) == 0)
{
strcpy(temp->next->name, temp->name);
temp->addy = temp->next->addy;
temp->salary = temp->next->salary;
toBeDeleted = temp->next;
temp->next = temp->next->next;
free(toBeDeleted);
printf("RECORD DELETED\n");
}
temp = temp->next;
printf("RECORD NOT FOUND\n");
}
void EDIT(struct data* head, char* name, struct address addr, float salary)
{
char edit[39];
scanf("%39s", edit);
struct data* temp = head;
while (strcmp(edit, temp->name) == 0)
{
temp->addy = addr;
temp->salary = salary;
printf("RECORD EDITED\n");
return;
}
temp = temp->next;
printf("RECORD NOT FOUND\n");
}
void CALCPAYROLL(struct data* head)
{
struct data* temp = head;
float total;
while (temp)
{
total += temp->salary;
temp = temp->next;
}
printf("total payroll: %f", total);
}
void HELP()
{
printf("commands:\n");
printf("List - shows the list of employees\n");
printf("Insert - Creates a new employee record\n");
printf("Delete - Deletes an existing employee record\n");
printf("Edit - Modifies the contents of an employee record\n");
printf("Payroll - Calculates and displays the total payroll\n");
printf("Help - Displays the set of available commands\n");
printf("Quit - Prints the message ""good bye!"" and exits the program" );
}
答案 0 :(得分:1)
首先,我要赞扬你做一个非常简洁的演讲。代码易读且易于理解。我发现它唯一的错误是所有大写名称通常都是为用#define
声明的宏和常量保留的。
下面:
struct data{
char name[39];
struct address addy;
float salary;
struct data *next;
} emp; // declaring a variable at the same time as the structure? Not very nice.
我看到在您创建第一个列表项(头部)时发生的问题。 Insert必须能够修改head
参数。这需要额外的间接水平。 INSERT还应返回错误代码,如果malloc失败,执行此操作的常用方法是在出错时返回负值(-1)。
void INSERT(struct data* head, char* name, struct address addr, float salary)
// should be
int INSERT(struct data** head, char* name, struct address addr, float salary)
当条目head
为NULL时,您必须稍微更改逻辑以使用新分配的缓冲区设置head
。然后调用INSERT成为。
if (INSERT(&head, name, &addr, salary) < 0)
{
// error !
}
我在INSERT中看到数据分配存在问题。
struct data* newEmployee = NULL;
//newEmployee = (struct data*)malloc(sizeof(emp)); // ?? you allocate a struct data, what's emp?
// should read
newEmployee = (struct data*)malloc(sizeof(struct data));
删除和编辑不起作用。他们找不到写的员工。您应该考虑使用find()函数,如下所示:
data* FindEmployeeData(data* head, const char* name)
{
while (head)
{
if (strcmp(head->name, name) == 0)
break;
head = head->next;
}
return head;
}
在为员工编写新业务时,这可以节省时间。
在INSERT中:
while(temp->next && temp->next->name > newEmployee->name)
我认为字符串应与strcmp()
...
在DELETE中:与INSERT相同,该函数可以更改列表的头部
int DELETE(data** head, const char* name); // returns -1 on error.
下面:
scanf("%s-%s-%s-%s-%s-%f", head->name, head->addy.street, head->addy.city, head->addy.state, head->addy.zip, &head->salary);
当用户输入的名称,地址,州,街道,城市或邮政编码对于您分配的空间而言太长时,会发生 。
答案 1 :(得分:0)
您无法访问数据,因为在INSERT函数头中必须是双指针,因为当您想在链表的头部插入某些内容时,您必须更改存储的地址在头上。在您的代码中,您正在修改头部的副本。请记住,在C 中,所有内容都是为值传递。这意味着要修改指针中的地址内容,您必须在函数中传递指针的地址。