簡體   English   中英

結構和鏈表苦苦掙扎

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM