我对我的语法有一些问题,它主要说我在"Struct CustomerInfo s“行的"struct”之前有一个错误;但是我似乎找不到问题。
我的程序应该问一个人想要做什么,首先,他们可以存储第一个选项的记录,然后存储在一个结构中,可以通过选择菜单的第二个选项来查看,如果他们选择第三个选项,那么他们显然就退出了程序。
如有任何帮助,将不胜感激。
#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;
发布于 2013-11-01 05:10:53
让我们从您创建的结构开始;接下来,我们将尝试查看它是否可以修复。我把细节放在一边,这样我们就可以看到大提纲:
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;,警告就会消失。
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,但是编译器会发出抱怨。原因在Why can't variables be declared in a switch statement?的优秀问答中得到了解释。
作为旁白--如果你能声明这样的变量--你在用它做什么?您的代码当前读取值并返回。但是,一旦您离开了变量的“作用域”(在您的例子中,因为您在s中声明了switch,这就是它的作用域),变量就消失了(用于它的内存被标记为“空闲”,并将被重用)。
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值指向的某个位置。这很可能会给您一个分割错误(访问“不属于您”的内存)。你应该做的是:
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
>> 3https://stackoverflow.com/questions/19719709
复制相似问题