簡體   English   中英

如何按升序排列結構數組中的結構?

[英]How can I arrange the structs in an array of structs in an ascending order?

如果這聽起來令人困惑,我很抱歉,我會盡量說清楚。 我有一個結構數組,其中數組存儲我定義為名片的結構。 但是,在將任何新名片添加到數組之前,我必須根據員工 ID 的整數值按升序存儲結構。

這是結構:

typedef struct{
int nameCardID;
char personName[20];
char companyName[20];
} NameCard;

因此,我嘗試使用關系運算符來比較 ID 的值,並將其按升序復制到另一個名為 fakeHolder 的臨時數組中,最后復制到實際數組中。 但是,在將我的數據輸入為 ID 9、7、5 后,我似乎無法理解為什么它不按順序排列。

這是我的輔助功能:

int addNameCard(NameCard *nc, int *size){
    int i = 0;
    // Why is this a pointer?
    NameCard fakeHolder[10];
    char dummy[100];
    char *p;
    printf("addNameCard():\n");
    if(*size == MAX){
        printf("The name card holder is full");
        // To quit the program
        return 0;
    }
    // Keeps it to Fake Name Card Holder First
    printf("Enter nameCardID:\n");
    scanf("%d", &fakeHolder->nameCardID);
    scanf("%c", &dummy);
    printf("Enter personName:\n");
    fgets(fakeHolder->personName, 20, stdin);
    if(p = strchr(fakeHolder->personName, '\n')){
        *p = '\0';
    }
    printf("Enter companyName:\n");
    fgets(fakeHolder->companyName, 20, stdin);
    if(p = strchr(fakeHolder->companyName, '\n')){
        *p = '\0';
    }
    // Compare the ID value
    for(int j = 0; j < *size; j += 1){
        if(fakeHolder->nameCardID == (nc+j)->nameCardID){
            printf("The nameCardID has already existed");
        }
        else if(fakeHolder->nameCardID < (nc+j)->nameCardID){
            fakeHolder[(j+1)].nameCardID = (nc+j)->nameCardID;
            strcpy(fakeHolder[(j+1)].personName,(nc+j)->personName);
            strcpy(fakeHolder[(j+1)].companyName, (nc+j)->companyName);
        }
    }
    *size += 1;
    // Transfer to the Actual Name Card Holder
    for(int k = 0; k < *size; k += 1){
        (nc+k)->nameCardID = fakeHolder[k].nameCardID;
        strcpy((nc+k)->personName, fakeHolder[k].personName);
        strcpy((nc+k)->companyName, fakeHolder[k].companyName);
    }
    printf("The name card has been added successfully\n");
    return 0;
}

您當前的代碼有幾個問題,您可以將其重寫為更易於維護和使用。 例如,

  • i (in int i = 0; ) 沒有被使用
  • scanf("%c", &dummy); 我假設是否有刪除尾隨的\\n - 但是用於讀取單個字符的 100 個字符的緩沖區是......令人驚訝。 請參閱scanf() 在緩沖區中保留新行字符,以了解有關“整數后尾隨內容”的不同方法的大量討論。
  • addNameCard拆分為 2 個函數,一個用於實際請求 NameCard,另一個用於將其插入到數組中,這樣可以更好地划分職責,並使您的程序更易於測試。 避免將輸入/輸出與程序邏輯混合。

你問的問題可以通過標准庫的qsort函數解決,如下:

#include <stdlib.h>

typedef struct{
    int nameCardID;
    char personName[20];
    char companyName[20];
} NameCard;

void show(NameCard *nc, int n) {    
    for (int i=0; i<n; i++, nc++) {
        printf("%d,%s,%s\n", 
            nc->nameCardID, nc->personName, nc->companyName);
    }
}

// comparison functions to qsort must return int and receive 2 const void * pointers
// they must then return 0 for equal, or <0 / >0 for lower/greater
int compareCardsById(const void *a, const void *b) {
    return ((NameCard *)a)->nameCardID - ((NameCard *)b)->nameCardID;
}

int main() {
    NameCard nc[10];
    nc[0] = (NameCard){1, "bill", "foo"};
    nc[1] = (NameCard){3, "joe", "bar"};
    nc[2] = (NameCard){2, "ben", "qux"};
    show(nc, 3);
    // calling the libraries' sort on the array; see "man qsort" for details
    qsort(nc, 3, sizeof(NameCard), compareCardsById);
    show(nc, 3);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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