[英]c programming structure error
我的语法有一些问题,它主要是说我在“结构CustomerInfo”行上的“struct”之前有一个错误;但我似乎没有找到问题。
我的程序应该首先询问这个人想要做什么,他们可以存储第一个选项的记录,然后存储在一个结构中,如果他们选择了菜单,可以通过选择菜单的第二个选项来查看。 3,然后他们显然退出了该计划。
任何帮助将不胜感激,谢谢。
#include <stdio.h>
void menu();
int id,first,last;
struct CustomerInfo
{
char FirstName[15]; /* These are the varibles for the customer infomation */
char LastName[20];
int ID;
};
int main()
{ /* program starts */
int selection = 0;
void menu()
{ /* Menu loop function */
do
{ /* menu start */
printf("\n\n - What would you like to do?");
printf("\n1 - Store a customer record");
printf("\n2 - View customer Records");
printf("\n3 - Quit program");
scanf("%i", &selection);
} while (selection > 3);
printf("You have entered an incorrect value"); /* If selection is greater than 3 then end program */
return 0;
}
switch(selection)
{
/* switch statement starts */
case 1:
struct CustomerInfo s;
printf("Please enter the customers details including First name, Lastname and ID.\n\n");
printf("Enter First name: ");
scanf("%s", s.FirstName); /* Option 1: Asks to enter the customers details to store then loops back to program */
printf("Enter Last name: ");
scanf("%s", s.LastName);
printf("Enter Customer ID: ");
scanf("%s", s.ID);
void menu();
break;
case 2:
printf("\nDisplaying Infomation\n");
printf("First name: %s\n",s.Firstname); /* Option 2: Prints the customer details as listed in option 1 */
printf("Last name: %s\n",s.Lastname);
printf("Customer ID: %s\n",s.ID);
void menu();
break;
case 3: /* Option 3: Program ends if option 3 is chosen. */
break;
}
返回0;
让我们先看看你创建的结构; 接下来我们将尝试查看它是否可以修复。 我要留下详细信息,以便我们可以看到大纲:
main {
struct{}
void menu(){
do {
stuff
} while (selection > 3)
printf("you have entered an incorrect value"); // if selection is > 3
}
switch(selection) {
// do something if selection is 1 or 2, exit if 3
}
您的代码中没有最终的结束括号。 我假设这是一个复制粘贴错误,所以我添加了它。 使用-Wall
进行编译(以获取警告以及报告的错误),我收到了许多错误:
sel.c:18: error: nested functions are disabled, use -fnested-functions to re-enable
sel.c: In function ‘menu’:
sel.c:31: warning: ‘return’ with a value, in function returning void
sel.c: In function ‘main’:
sel.c:38: error: expected expression before ‘struct’
sel.c:41: error: ‘s’ undeclared (first use in this function)
sel.c:41: error: (Each undeclared identifier is reported only once
sel.c:41: error: for each function it appears in.)
sel.c:61: warning: control reaches end of non-void function
让我们依次看看:
sel.c:18: error: nested functions are disabled, use -fnested-functions to re-enable
将一个函数放在另一个函数中是“嵌套”。 您很少想要这样做 - 这意味着当您在另一个函数内部时,该函数只是“可见”(有点像局部变量,但对于函数)。 它不是标准C - 它是gcc
的扩展。 使用非标准(因此非便携式)扩展几乎总是一个坏主意。 请参阅http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
sel.c: In function ‘menu’:
sel.c:31: warning: ‘return’ with a value, in function returning void
当我们声明一个函数void
,我们说它不会返回一个值。 当你有一个像return 0;
的声明return 0;
你正在返回一个值。 编译器将忽略它 - 但它警告你说了一件事,然后做了另一件事。 只需使用return;
没有参数,警告消失了。
sel.c:38: error: expected expression before ‘struct’
sel.c:41: error: ‘s’ undeclared (first use in this function)
sel.c:41: error: (Each undeclared identifier is reported only once
sel.c:41: error: for each function it appears in.)
这是最棘手的一个。 你会期望你在第38行正确地声明了变量s
- 但编译器抱怨。 原因在于为什么不能在switch语句中声明变量的优秀Q&A中解释了这个原因?
顺便说一句 - 如果你可以声明一个这样的变量 - 你用它做什么? 您的代码当前读入值并返回。 但是一旦你离开变量的“范围”(在你的情况下,因为你在switch
声明了s
,那将是它的范围)变量就会消失(用于它的内存被标记为“free”并且将会被重复使用。)
sel.c:61: warning: control reaches end of non-void function
这表示您已到达期望返回值的函数的末尾,但您没有return someValue;
陈述的类型。 再次 - 这只会导致一个警告,因为如果没有给出值,默认行为是返回0
,但它表示你说了一件事并做了另一件事。
到目前为止,我刚刚解释了编译器给出的错误。 让我们更仔细地看一下代码结构。 我认为你想做的是这样的:
define customerInfo structure
define menu function
main()
repeat:
call menu, get selection
switch(selection):
case 1: create new record
case 2: display records
case 3: quit program
为了使这项工作,我们需要对您的程序进行一些更改。 首先 - 让我们将menu
功能定义移到main
函数之外,这样我们就有了可移植的代码。 第二 - 如果我们希望能够创建多个客户记录,我们需要将它们存储在一个数组中。 你真的想要一个列表,这样你就可以无限期地扩展,但是让它保持简单并允许最多10条记录。 然后我们需要改进菜单功能的逻辑(如果选择不是1,2或3你给出一条消息并再试一次;在你当前的代码中该行
printf("You have entered an incorrect value");
在你退出测试不正确值的循环之后才会执行...所以当你最终到达那里时,值是有效的,而不是无效的。
在我们真正编写“正确”代码之前,还有另一件值得注意的事情。 使用scanf
读取值时,您可以执行以下操作:
scanf("%s", s.FirstName);
这是正确的,因为s.FirstName
是一个指向字符串开头的指针。 但是,您为字符串分配了有限的空间(即15个字符,包括终止'\\0'
),因此如果有人输入长名称,您的程序将崩溃。 “良好的防御性编码”要求你抓住这个 - 例如使用
scanf("%14s", s.FirstName);
这说“读不超过14个字符”。 有更好的技巧,但至少这是一个开始。 但是,当你这样做时,你实际上犯了一个错误
scanf("%s", s.ID);
由于ID
被定义为一个int
,现在你正在将一个字符串读入...而不仅仅是它的地址,而是读到某个位置,该位置由s.ID
的值s.ID
。 这很可能会给你一个分段错误(访问“不属于你”的内存)。 你应该这样做:
scanf("%d", &s.ID);
“将整数读入s.ID
的位置”
另外 - 在某些地方你使用FirstName
,而在其他地方你使用Firstname
。 同上LastName
。 资本化很重要 - 当您修复其他编译器错误时,这些错误将开始出现。
由于您似乎希望能够读取多个客户记录,因此我们需要一系列记录; 正如我上面所说,我们必须确保数组在switch语句的范围内可用,并“存活”该语句(因此您可以使用它执行某些操作)。 把所有这些东西放在一起让我们得到这样的东西:
#include <stdio.h>
// define function prototype:
int menu();
struct CustomerInfo
{
char FirstName[15]; /* These are the variables for the customer infomation */
char LastName[20];
int ID;
};
int menu()
{ /* Menu loop function */
int flag = 0;
int selection;
do
{ /* menu start */
if(flag > 0) printf("You have entered an incorrect value"); /* If selection is greater than 3 then end program */
printf("\n\n - What would you like to do?");
printf("\n1 - Store a customer record");
printf("\n2 - View customer Records");
printf("\n3 - Quit program\n>> ");
scanf("%i", &selection);
flag++;
} while (flag < 10 && (selection < 0 ||selection > 3));
return selection;
}
int main(void)
{ /* program starts */
struct CustomerInfo s[10];
int selection;
int customerCount = 0;
while(1) {
int ii; // loop counter we will need later
selection = menu();
switch(selection)
{
case 1:
printf("Please enter the customers details including First name, Lastname and ID.\n\n");
printf("Enter First name: ");
scanf("%s", s[customerCount].FirstName); /* Option 1: Asks to enter the customers details to store then loops back to program */
printf("Enter Last name: ");
scanf("%s", s[customerCount].LastName);
printf("Enter Customer ID: ");
scanf("%d", &s[customerCount].ID);
customerCount++;
break;
case 2:
printf("\nDisplaying Infomation\n");
for(ii = 0; ii < customerCount; ii++) {
printf("First name: %s\n",s[ii].FirstName); /* Option 2: Prints the customer details as listed in option 1 */
printf("Last name: %s\n",s[ii].LastName);
printf("Customer ID: %d\n---\n",s[ii].ID);
}
break;
case 3: /* Option 3: Program ends if option 3 is chosen. */
return 0; // program returns
break;
}
}
}
测试输出:
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> 1
Please enter the customers details including First name, Lastname and ID.
Enter First name: John
Enter Last name: Smith
Enter Customer ID: 123
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> 5
You have entered an incorrect value
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> -1
You have entered an incorrect value
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> 1
Please enter the customers details including First name, Lastname and ID.
Enter First name: Harry
Enter Last name: Jones
Enter Customer ID: 654
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> 2
Displaying Infomation
First name: John
Last name: Smith
Customer ID: 123
---
First name: Harry
Last name: Jones
Customer ID: 654
---
- What would you like to do?
1 - Store a customer record
2 - View customer Records
3 - Quit program
>> 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.