2011-05-03 101 views
3

我正在用c寫一個簡單的程序,所以我可以更好地理解語言,但是我有一個奇怪的問題。 正如你從下面的代碼中看到的,我只有一個循環,當我插入255作爲一個值時它退出。問題是,當我選擇第一(插入選項)後,我插入一個名字在節目開始像一個循環,並給了我所有的時間選擇畫面......C中的循環問題

#include<stdio.h> 
#include<stdlib.h> 
struct student{ 
    char *name; 
    int id; 
    }; 
void insertStudent(void); 
struct student * init(void);  

int main(){ 
    struct student *p; 
    int selectionCode=0; 

    while(selectionCode!=255){ 
     printf("\nInsert students:1"); 
     printf("\nDisplay students:2"); 
     printf("\nExit:255"); 
     printf("\n\nEnter selection:"); 
     scanf("%d",&selectionCode); 

     p=init(); 

     switch(selectionCode){ 
      case 1: 
      insertStudent(); 
      //printf("1\n"); 
      break; 
      case 2: 
      //printf("2\n"); 
      break; 
      case 255: 
      break; 
      } 
     } 

    //p->name="stelios"; 
    //p->id=0; 
    //printf("Name:%s ID:%d",p->name,p->id); 
    //free(p); 
    //p=NULL; 

    return 0; 
} 
struct student *init(void) 
{ 
    struct student *p; 
    p=(struct student *)malloc(sizeof(struct student)); 
    return p; 
} 
void insertStudent(void){ 
    struct student *p; 
    p=init(); 
    printf("Enter Name:"); 
    scanf("%s",p->name);//return 1; 
    printf("Enter ID:"); 
    scanf("%d",&p->id); 
    //printf("test"); 
    } 
+0

是的,這將是。但是你不想每次都選擇屏幕? – 2011-05-03 14:05:29

+0

@Doug T.Nope它不是作業。我知道Java,現在我正在學習C ... – Stelios 2011-05-03 14:10:32

回答

2

部分問題可能是該代碼沒有爲該結構中的name字段分配內存。 init函數分配一個新的結構,但不會初始化name字段。然後insertStudent函數使用scanf來讀入該未初始化的指針。這會導致寫入「隨機」內存,並可能導致任何數量的問題,包括訪問衝突。

+0

你是對的,我改變指針到數組(名稱[30]),它的工作。但是,如果我想使用指針,我怎麼能分配結構內的內存? – Stelios 2011-05-03 14:44:59

+0

@Stelios:要使用指針,您需要在分配結構本身之後再次調用malloc。'p-> name = malloc(30);'。如果您堅持使用固定大小,則使用該數組可能更簡單/更好(名稱[30])。但是,如果您稍後想要更改大小,那麼使用malloc就可以實現(然後可以釋放並再次使用malloc或使用realloc)。 – 2011-05-03 15:27:24

0

看起來你有一個內存泄漏,我將p傳入insertStudent()。

在insertStudent()調用中間還有一個return 1;,所以在完成工作之前它會返回。

0

您需要刪除「return 1;」來自insertStudent,否則就不會編譯。你應該用malloc初始化p-> name,並改變「scanf(」%s「,p-> name);」到「scanf(」%s「,& p-> name);」,因爲你需要一個指向* char的指針。

+0

你是對的回報只是我忘了評論它。 &p->名稱不正確,因爲如果我想使用&我應該有這種形式&* p->名稱。我已經運行它,以防萬一,我是對的。 – Stelios 2011-05-03 14:24:19

+0

是的,你是正確的與scanf。 – 2011-05-03 18:37:22

0

你有「返回1;」掃描完名後。從邏輯上看,你不應該在這一點上返回,因爲你想輸入ID。此外,你聲明該函數返回「無效」,所以返回一個是錯誤。

編輯:真正的問題是,您從來沒有爲名稱字符串分配空間。

0

嘗試:

struct student *insertStudent(void){ 
struct student *p; 
p=init(); 
printf("Enter Name:"); 
scanf("%s",p->name); 
printf("Enter ID:"); 
scanf("%d",&p->id); 
//printf("test"); 
return p; 
} 

在主

case 1: 
free(p); 
    p=insertStudent(); 
    //printf("1\n"); 

在您需要的名稱分配空間初始化。

+0

我出現了分段錯誤,可能是因爲p沒有初始化。即使初始化它也循環..在初始化函數 – Stelios 2011-05-03 14:18:29

+0

你如何分配內存的名稱? – Iraklis 2011-05-03 14:24:15

0

什麼是混亂...... :-) 你從來沒有malloc()爲p->名稱的緩衝區,但是如果使用scanf()填充。 這會破壞程序的內存。 此外......在你的函數中,你也使用變量p和主程序。 這不是同一個變量,但你似乎認爲它是。 另一個問題:返回1;在scanf()中止insertStudent()函數之後,「輸入ID」從不執行。 這是一個無效函數,所以它不應該返回一個值,順便說一下。編譯器可能已經發出警告。

它可能有更多的錯誤,但這是我發現之後立即給它一次。