我正在尝试为有关结构的作业创建一个程序。我们的想法是创建一个包含名字和姓氏,电话号码和电子邮件地址变量的结构。我认为我的大多数代码都没问题 - 或许与C的现代编码标准相比还不成熟,但它就是我在课堂上的所在。
无论如何,我在试图初始化电子邮件地址字段的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;
}
答案 0 :(得分: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
的前五个字节将是'h'
,'e'
,'l'
,'l'
,'o'
以及每个字节剩下的95个字节的值为0。
int iEntry1, iEntry2, iEntry3, iEntry4, iEntry5 = 0;
仅初始化iEntry5 = 0
。 iEntry1
.. iEntry4
未被初始化,这可能不是您的意图。
打印输入提示时,you should call fflush(stdout)
afterward。
另外,请勿使用scanf
。 It is error-prone and is hard to use correctly.您特别需要关注缓冲区溢出。
答案 1 :(得分:2)
每个联系人都有十个号码(int number[10]
,从0到9),您的分配就像是一个简单的int number
:
myContact[0].number = 0;
另外,不要这样做:
strcpy(myContact[0].fname, "\0");
你可能想要“”,而不是“\ 0”,因为字符串末尾总是有一个隐含的\ 0。
(我希望fname和lname就像练习一样。世界上很多人的名字都不适合“名字 - 姓氏”范例)