2011-12-03 89 views
0

我正在做一個書練習(不是作業,因爲我是自學的),在這本練習中,我應該用一個類型爲struct的數組寫一本電話簿。 所以我定義:檢查C結構數組中的成員元素的內容

typedef struct contact { 

    char cFirstName[10]; 
    char cLastName[10]; 
    char iTelphone[12]; 

} address ; // end type 

接着,我定義:

address myContacts[5] = { 
         { 
       { '\0' } // inner most braces, 
          // tell gcc to put 0 in all 
         // members of each struct ? 
       } // first braces, tell gcc we have a 
        // a struct as array member 
       }; // outer most braces, tell gcc we have 
        // an array 

現在我有打印內容陣列的功能。 但是,我不想打印所有的數組,因爲我只對 感興趣的成員不爲空的數組元素。所以,我試過如下:

void printContacts(address * myContacts){ 
    printf("Inside printContacts"); 
    int i = 0; 

    while (i < 5) { 
     if (myContacts[i].cFirstName == NULL) 
      printf("%s", myContacts[i].cFirstName); //does not work 

     if (myContacts[i].cFirstName == '\0') 
      printf("%s", myContacts[i].cFirstName); //does not work 

     if (myContacts[i].cFirstName[0] != 0) 
     { 
      printf("%s", myContacts[i].cFirstName); //does work! 
     } 
     i++; 
    } 
} 

所以,我的問題是:

  1. 我是否初始化數組元素的成員,真正做到零(例如cFirstName [10])?
  2. 有沒有更好的方法?
  3. 如何檢查數組元素成員是否爲空?

在此先感謝您的答案!

回答

1

所以,我的問題是:

Am I initializing the array elements members to be really null (e.g cFirstName[10]) ? 
Is there a better way ? 
How can I check that an array element member is empty ? 

預先感謝您的回答!

你在初始化你的結構數組中做了什麼可以改進。

第一支桿說, 「初始化與我的內容的數組:」

地址myContacts [5] = {...}

第二組括號說,「初始化在所述第一結構該陣列如下:」

address myContacts[5] = { 
    { ... } , // each of these braces initializes a different struct in the 
    { ... } , // array (there are five inner brace sets as there are five 
    { ... } , // structs in the array). 
    { ... } , 
    { ... } 
} 

請注意,這是很好的形式來初始化所有的數組元素的一次,或者使用 for循環這樣做。這就是你原來的初始化讓我困惑的原因。即使運行,我也不確定它是否「正確」。

然後,你把更多的括號內的那些(如果你還想做這個應用程序支柱初始化)在結構初始化數組:

address myContacts[5] = { 
    {{'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}, 
    {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}, 
    {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0, '\0', '\0'} }, 
    . 
    . 
    . 
} 

這是「歸零」的方式您的數組首先使用括號表示法。沒有太多的人這麼做;它變得乏味。通常,對於一個真正的應用程序的人會使用堆(內存,你可以分配在即時,如下圖所示),這樣的事情,在這種情況下,你可以簡單地在你的結構中使用指針:

typedef struct contact { 

    char *cFirstName; 
    char *cLastName; 
    char *iTelphone; 

} address ; // end type 

你可以這樣分配一個聯繫人列表:

address *myContacts = (address*) malloc(sizeof(address)*5); 
         // the above allocates a five-element array 
int i; 
for (i = 0; i < 5; i++) 
{ 
    myContacts[i].cFirstName = NULL; 
    myContacts[i].cLastName = NULL; 
    myContacts[i].iTelephone = NULL; 
} 

分配字符串時,你需要添加到地址簿:

myContacts[0].cFirstName = (char*) malloc(sizeof(char)*20); 
strcpy(myContacts[0].cFirstName,"Tom, Dick, or Harry"); 

,當你做,免費的一切你分配d:

int i; 
for (i = 0; i < 5; i++) 
{ 
    if (myContacts[i].cFirstName != NULL) // since we initialized all pointers 
    {          // to null, this only isn't null when 
     free(myContacts[i].cFirstName); // it's been previously allocated 
    } 
    if (myContacts[i].cLastName != NULL) 
    {          
     free(myContacts[i].cLastName); 
    } 
    if (myContacts[i].iTelephone != NULL) 
    {          
     free(myContacts[i].iTelephone); 
    } 
} 

這允許您創建可變長度的字符串,任意大的聯繫人列表,如果你想檢查是否一個條目是空的,只是檢查,看看它的指針是空的:

if (myContacts[i].cFirstName != NULL) 
{ 
    printf("%s", myContacts[i].cFirstName); //does work! 
} 

我希望這個概念至少對你有用,即使你最終沒有使用malloc(在每個程序中都有很好的理由或反對使用它)。 :)

+0

感謝您的全面解答!我其實想接受每個人的答案。有很多關於C的知識,我正在使用的2本書沒有顯示所有這些細微差別! – Oz123

0

您應該檢查myContacts[i].cFirstName[0],因爲myContacts[i].cFirstName是指向char數組的指針。


詳細解釋

關於第一個問題:是的,你已經初始化的myContacts空的所有元素。前兩次測試失敗的原因是myContacts[i].cFirstName是指向char數組的指針,它不是NULL。當您定義myContacts陣列時,它將駐留在堆棧上,而myContacts[i]指向堆棧上的某個地址/地址,而不是NULL

第二:您還可以通過

address myContacts[5]; // define an address array with 5 elements 
memset((void*)myContacts, 0, sizeof(myContacts)); 

初始化數組,但不知道哪一個是效率更好。

+0

您也只初始化第一個。 – RedComet

+0

@RedComet檢查它。 :) –

1

你實際上創建結構,並與0 paddint它,因此,病情myContacts[i].cFirstName == NULL絕不會因爲你創建一個靜態數組是真實的,它會工作只有當你宣佈cFirstName作爲一個指針(char*)你結構。

此外,您的第二個條件與第一個條件基本相同,因爲NULL只是0的預處理器常量。

要測試一個字符串是否爲空,通常將第一個字符與0進行比較,就像在上次測試中一樣。

2

你的初始化方法在某種程度上是不尋常的,因爲它實質上是對結構進行了調零,你可以將memset(&MyContacts,0,sizeof(address)*5)置於NULL,你的結構中的所有東西。

你不能檢查一個數組是否爲「空」,因爲在一般意義上NULL是一個有效的元素。如果你確定只有一個C字符串將被包含在數組中,那麼你只需要檢查第一個元素是否爲NULL。由於所有C字符串始終以NULL結尾,這意味着您必須始終在字符串末尾添加終止NULL。

+0

'memset(&MyContacts,0,sizeof(地址)'只初始化一個地址,不是5個全部。:) –

+0

新增了5 – RedComet

1

我初始化數組元素成員是真正的空(例如cFirstName [10])?

您基本上將字符串緩衝區的第一個字符指定爲'\ 0'(或者等於0。)

例如,以下變量的值name指的是指向字符串緩衝區的指針。所以在這種情況下,如果您將指針與0或'\ 0'進行比較,它們將不相等。

int i; 
char name[10] = {'\0'}; 

printf("Raw content: "); 
for(i = 0 ; i < 10 ; ++i) 
    printf("%2d ", name[i]); 
printf("\n\n"); 

printf("name = %p\n\n", name); 
printf("*name = %d, name[0] = %d\n\n", *name, name[0]); 

這給:

Raw content: 0 0 0 0 0 0 0 0 0 0 

name = 0012FF48 

*name = 0, name[0] = 0 

如果不是名稱設置爲 「Hello」:

Raw content: 72 101 108 108 111 0 0 0 0 0 

name = 0012FF48 

*name = 72, name[0] = 72 

有沒有更好的辦法?

不知道我是否正確地得到了您的問題:要確保數組x的每個元素都設置爲值y,您可以使用memset函數。

如何檢查數組元素成員是否爲空?

要檢查空字符串,可以使用strlen函數查找以'\ 0'結尾的字符串的長度。