1

我的语法有一些问题,主要是说我在“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;

4

1 回答 1

3

让我们从查看您创建的结构开始;接下来我们将尝试看看它是否可以修复。我省略了细节,所以我们可以看到大轮廓:

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.)

这是最棘手的一个。您会期望您s在第 38 行正确声明了一个变量 - 但编译器会抱怨。为什么不能在 switch 语句中声明变量

顺便说一句——如果你可以声明一个这样的变量——你在用它做什么?您的代码当前读取值并返回。但是,一旦您离开变量的“范围”(在您的情况下,因为您sswitch. -用过的。)

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
>> 3
于 2013-11-01T05:10:53.077 回答