2011-08-31 27 views
0

這是一個家庭作業問題。我的編譯器是CodeBlocks。使用for循環中的struct問題

這裏是我的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct Address{ 
    char number[5]; 
    char street[30]; 
    char city[30]; 
}; 

struct Employee{ 
    char ID[7]; 
    char name[31]; 
    struct Address *addr; 
}; 

int main(){ 
    int n,i; 
    char temp[7]; 
    printf("Enter number of Employee : "); 
    scanf("%d",&n); 
    struct Employee **p=(struct Employee **)malloc(n*sizeof(struct Employee *)); 

    for (i=0; i<n; i++) 
    { 
     p[i]=(struct Employee *)malloc(sizeof(struct Employee)); 
     p[i]->addr=(struct Address *)malloc(sizeof(struct Address)); 
    } 

    for(i=0; i<n; i++) 
    { 
     printf("Employee #%d\n",i+1); 
     printf("Enter ID : "); 
     gets(p[i]->ID); 
     printf("Enter Name : "); 
     gets(p[i]->name); 
     printf("Enter Home number : "); 
     gets(p[i]->addr->number); 
     printf("Enter Street : "); 
     gets(p[i]->addr->street); 
     printf("Enter City : "); 
     gets(p[i]->addr->city); 
    } 
} 

我的問題是,當我運行這段代碼,我不能爲#1名員工輸入ID;但是,我可以輸入員工#2和#3的ID。

我的問題在哪裏?

+2

因爲'scanf'在後面留下換行符。也不要使用'gets',你的代碼是可怕的(沒有冒犯,但所有那些(非常小!)固定大小的緩衝區,沒有檢查...) – user786653

+0

我秒這。考慮閱讀['getline'](http://www.crasseux.com/books/ctutorial/getline.html#getline),並使用'strncpy'將行的第一個'n'字符複製到結構字段中。 –

+0

也沒有必要施放'malloc'的返回。 –

回答

1

似乎有一些問題,gets()在循環的第一遍之前從控制檯讀取一些東西。

在循環似乎解決它之前添加gets(temp);。更好的解決方案是使用除get()之外的其他東西。

+1

嗯,如果我們只是想快速修復,我更喜歡'scanf(「%d [\ n]」,&n);' – user786653

+0

是的,這段代碼太糟糕了,我不能讓自己做任何事情,只是一個快速入侵。 :-)一旦他的工作成績達到要求,教練就可以對整個結果進行評分。 –

0

初始scanf("%d", &n);不消耗尾隨換行符,因此它可用於gets()調用。

順便提一句,從不使用gets()。它不能安全使用。例如,如果您正在讀取一個6字節的數組,並且用戶輸入了10個字符,則會發生緩衝區溢出。考慮使用fgets()代替(但請注意,與gets()不同,它將'\n'字符留在緩衝區中)。

+0

如果它的第二個參數很小,fgets還會在緩衝區中留下'\ n'。 – user411313

+0

@ user411313:通過「緩衝區」,我的意思是它存儲該行的數組。如果length參數足夠大(或者輸入的行很短),則字符串的末尾會有一個'\ n'';如果不是,只讀取一部分行,其中不包括''\ n'',它將保留下一個輸入操作。你仍然需要做一些額外的工作,在存在很長的輸入行的情況下保持100%的穩定性,但是對於這樣一個簡單的練習,只需要使目標數組足夠大並忽略問題就可能了。 (這當然比'gets()'好。) –

0

您應該在任何用戶輸入後清楚地清除輸入緩衝區。而且你應該讓大小限制器的輸入安全。你應該使用scanf的返回值。

scanf("%d",&n);while(getchar()!='\n'); 
... 
scanf("%6[^\n]",p[i]->ID);while(getchar()!='\n'); 
... 
scanf("%30[^\n]",p[i]->name);while(getchar()!='\n'); 
... 
scanf("%4[^\n]",p[i]->addr->number);while(getchar()!='\n'); 
... 
scanf("%29[^\n]",p[i]->addr->street);while(getchar()!='\n'); 
... 
scanf("%29[^\n]",p[i]->addr->city);while(getchar()!='\n');