[英]C structs and linked lists struggle
因此,我們剛開始在在線課程中學習鏈接列表和數據結構,但是我一直在為這個主題而苦苦掙扎。 我對指針有一個大致的了解,但是當您將所有內容組合在一起時,我會完全迷失方向。
因此,對於該程序,我應該處理員工數據並通過使用結構和指針來訪問它。 但是,我認為我沒有將正確的值傳遞給函數,因為沒有保存數據並且無法訪問它。 任何幫助,將不勝感激。
#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" );
}
首先,我要向您推薦一個非常簡潔的演示文稿。 該代碼可讀性強,易於遵循。 我發現的唯一錯誤是,所有大寫名稱通常都保留給#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.
我看到在創建第一個列表項“ head”時發生的問題。 插入必須具有修改head
參數的方法。 這需要額外的間接級別。 如果malloc失敗,則INSERT還應該返回錯誤代碼,通常的方法是在錯誤時返回負值(-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);
當用戶輸入的名稱,地址,州,街道,城市或郵政編碼對於您分配的空間而言過長時, 將會發生可怕的事情。
您無法訪問數據,因為在INSERT函數中head必須是雙指針 ,因為當您想在鏈接列表的head中插入某些內容時,必須更改存儲在head中的地址。 在您的代碼中,您正在修改head的副本 。 記住在C語言中一切都是為了價值而傳遞的 。 這意味着要修改指針中的地址內容,必須在函數處傳遞指針的地址 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.