簡體   English   中英

c編程結構錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM