2013-03-16 67 views
-1

我正在嘗試爲有關結構的賦值創建程序。這個想法是創建一個包含姓名,電話號碼和電子郵件地址變量的結構。我認爲我的大部分代碼都可以 - 與C的現代編碼標準相比,可能是最基本的代碼,但這是我在課堂上的地方。C:嘗試初始化結構中的char數組時出現賦值錯誤時的不兼容類型

無論如何,我試圖初始化電子郵件地址字段中的5行上出現編譯錯誤,說明賦值中的不兼容類型。但是,我不會在首字母或姓氏字段中看到這些錯誤,但我不明白爲什麼。

任何想法,爲什麼發生這種情況,或與程序其餘部分的錯誤,非常感激!我不能真正調試它的其餘部分,直到我解決了這個編譯錯誤,所以我不確定還有什麼問題。

#include <stdio.h> 
#include <string.h> 

/***************************************** 
Structure declaration, creating type cont 
*****************************************/ 

typedef struct contact { 
    char fname[20]; 
    char lname[20]; 
    int number[10]; 
    char email[30]; 
} cont; 

/***************************************** 
Start of main function 
*****************************************/ 
int main() { 

int iMenu; //variable required for the menu 
int iStorage; //variable used to store array entry chosen by the user 
int iEntry1, iEntry2, iEntry3, iEntry4, iEntry5 = 0; //variables used for flagging assigned entries 
/******************************************* 
because of the typedef declaration, the struct command 
isn't necessary in creating an instance of the structure. 
*******************************************/ 
cont myContact[4]; 

/******************************************* 
we initialize the arrays contained within the structures 
*******************************************/ 

    strcpy(myContact[0].fname, "\0"); 
    strcpy(myContact[0].lname, "\0"); 
    myContact[0].number = 0; 
    strcpy(myContact[0].email, "\0"); 
    strcpy(myContact[1].fname, "\0"); 
    strcpy(myContact[1].lname, "\0"); 
    myContact[1].number = 0; 
    strcpy(myContact[1].email, "\0"); 
    strcpy(myContact[2].fname, "\0"); 
    strcpy(myContact[2].lname, "\0"); 
    myContact[2].number = 0; 
    strcpy(myContact[2].email, "\0"); 
    strcpy(myContact[3].fname, "\0"); 
    strcpy(myContact[3].lname, "\0"); 
    myContact[3].number = 0; 
    strcpy(myContact[3].email, "\0"); 
    strcpy(myContact[4].fname, "\0"); 
    strcpy(myContact[4].lname, "\0"); 
    myContact[4].number = 0; 
    strcpy(myContact[4].email, "\0"); 


/***************************************** 
Creation of the menu to allow the users 
to add entries or view them 
*****************************************/ 
while (iMenu != 3) { 
printf("Please select one of the following menu options: \n"); 
printf("\n1. Input new entries into the phonebook"); 
printf("\n2. View entries stored in the phonebook"); 
printf("\n3. Exit the Program\n"); 
scanf("%d", &iMenu); 

/******************************************* 
First menu option allows the selection of which 
entry, and the storage of phonebook data 
********************************************/ 
    if (iMenu == 1) { 
    printf("Please input the entry in the phonebook you wish to change (0-4): \n"); 
    scanf("%d", iStorage); 
    printf("Please input the first name of your new contact: \n"); 
    scanf("%s", myContact[iStorage].fname); 
    printf("Please input the last name of your new contact: \n"); 
    scanf("%s", myContact[iStorage].lname); 
    printf("Please input the phone number of your new contact: \n"); 
    scanf("%d", myContact[iStorage].number); 
    printf("Please input the e-mail address of your new contact: \n"); 
    scanf("%s", myContact[iStorage].email); 

    /************************************** 
    Nested if statement sets the variable to 
    flag if an entry has been made 
    **************************************/ 
    if (iStorage == 0) 
     iEntry1 = 1; 
    else if (iStorage == 1) 
     iEntry2 = 1; 
    else if (iStorage == 2) 
     iEntry3 = 1; 
    else if (iStorage == 3) 
     iEntry4 = 1; 
    else if (iStorage == 4) 
     iEntry5 = 1; 
    } 

    /*************************************** 
    Menu option 2 allows the user to display 
    stored phonebook entries, using the iEntry 
    variables as flags to determine which ones 
    to display 
    ***************************************/ 
    else if (iMenu == 2) { 
    if (iEntry1 == 1) 
     printf("%s %s phone number: %d e-mail address: %s", myContact[0].fname, myContact[0].lname, myContact[0].number, myContact[0].email); 
    if (iEntry2 == 1) 
     printf("%s %s phone number: %d e-mail address: %s", myContact[1].fname, myContact[1].lname, myContact[1].number, myContact[1].email); 
    if (iEntry3 == 1) 
     printf("%s %s phone number: %d e-mail address: %s", myContact[2].fname, myContact[2].lname, myContact[2].number, myContact[2].email); 
    if (iEntry4 == 1) 
     printf("%s %s phone number: %d e-mail address: %s", myContact[3].fname, myContact[3].lname, myContact[3].number, myContact[3].email); 
    if (iEntry5 == 1) 
     printf("%s %s phone number: %d e-mail address: %s", myContact[4].fname, myContact[4].lname, myContact[4].number, myContact[4].email); 
    } 
    else if (iMenu > 3) { 
    printf("Invalid Entry."); 
    } 
} 


return 0; 
} 
+1

cont myContact [4];給你4個內存插槽你如何訪問5個插槽(0到4)和數組是如何分配一個整數到整數陣列 – Civa 2013-03-16 05:24:46

回答

3

你的編譯器幾乎可以肯定在抱怨這些線路:

myContact[0].number = 0; 
myContact[1].number = 0; 
... 

這些:

strcpy(myContact[0].email, "\0"); 
strcpy(myContact[1].email, "\0"); 
... 

struct contact宣佈其number字段的類型爲int[10],但您正在嘗試爲其分配單個int

其他不請自來的建議:

你可以爲更簡單的初始化myContact陣列:

cont myContact[4] = { { { 0 } } }; 

當初始化一個聚合類型的一部分(例如數組,struct),編譯器會自動初始化其餘所有成員。例如,如果你有:

char s[100] = "hello"; 

接着的s前5個字節將是'h''e''l''l''o',並且每個餘下的95個字節的將具有值0。

int iEntry1, iEntry2, iEntry3, iEntry4, iEntry5 = 0; 

這隻初始化iEntry5 = 0iEntry1 .. iEntry4未被初始化,這可能不是你想要的。

打印提示輸入時,you should call fflush(stdout) afterward

另外,請勿使用scanfIt is error-prone and is hard to use correctly.您特別需要關注緩衝區溢出問題。

+0

「編譯器將零初始化未明確初始化的所有成員。」我的教科書告訴我們,始終初始化變量很重要,因爲在c中,那些變量將包含變量分配給內存中的任何數據。因此,一旦編譯,未初始化的變量不是問題嗎?自己初始化它們仍然是最佳實踐嗎? – CDAGeek 2013-03-16 06:02:21

+0

@CDAGeek:我特別說過,編譯器會將未初始化的* members *初始化爲零。這指的是一個* aggregate *類型的成員(例如一個數組,一個'struct')。初始化聚合的一部分時,您將自動初始化其餘部分。對於個體變量這不是真的,所以是的,你應該初始化這些變量。 (並且請注意,您仍然需要初始化部分聚合。)我將編輯我的答案以使其更清晰。 – jamesdlin 2013-03-16 06:04:37

+0

非常感謝您的幫助,在您指出的衆多小修復之後,我能夠獲得工作。此外,非常感謝scanf和fflush(stdout)的提示,我將更深入地研究這些代碼,以便我的代碼符合標準。 – CDAGeek 2013-03-16 06:34:01

2

每個聯繫人都有十個數字(int number[10],從0至9),並且您分配,如果它是一個簡單的int number

myContact[0].number = 0;

而且,不這樣做: strcpy(myContact[0].fname, "\0");

您可能想要「」,而不是「\ 0」,因爲在字符串末尾總是有一個隱含的\ 0。

(我希望FNAME和LNAME在那裏只是作爲一個練習,許多人在世界上有不適合的名字。「第一個名字 - 姓氏」範式)

+0

@jamesdlin我在這些行中固定空字符「」,以及int數組只是整數。我正在摸索着通過這件事的方式。我從這裏明白不使用scanf,什麼是好的選擇? Scanf是我們的文本用於接收輸入的唯一功能。此外,是的,這只是一個練習,而不是一個真實世界的應用程序。修復這些錯誤修復了編譯錯誤,但是當我嘗試使用菜單選項1實際上放置信息時,我現在正在出現分段錯誤。任何其他幫助表示讚賞。 – CDAGeek 2013-03-16 05:41:18

+0

不要忘記您希望scanf分配給的變量(字符串除外)之前的&。您可以使用fgets讀取所有輸入,並使用sscanf解析它(sscanf與scanf的不同之處在於sscanf從內存字符串中讀取數據,從而更容易檢查調試器中的程序狀態並從讀取錯誤中恢復) 。打開你的編譯器的警告,它會告訴你很多有趣的事情:-) – marcus 2013-03-16 05:53:22

+0

@CDAGeek:你回答了錯誤的問題。至於用什麼來代替'scanf',請閱讀我在答案中包含的鏈接。 – jamesdlin 2013-03-16 05:58:01

相關問題