這段時間在學習C語言,寫了下面這樣一段代碼
struct student
{
char name[50];
char number[12];
struct student *next;
};
int main()
{
struct student * head,*p,*temp;
head=(struct student *)malloc(sizeof(struct student));
if(head==NULL)
{
printf("分配記憶體失敗!");
exit(0);
}
else
{
head->next=NULL;
p=head;
int iCount=0;
printf("請輸入學生個數:");
scanf("%d",&iCount);
int i;
for(i=0;i<iCount;i++)
{
temp=(struct student *)malloc(sizeof(struct student));
if(temp==NULL)
{
printf("分配記憶體失敗!");
exit(0);
}
else
{
printf("請輸入第%d個學生的姓名:",i+1);
gets(temp->name);
printf("請輸入第%d個學生的學號:",i+1);
gets(temp->number);
temp->next=NULL;
p->next=temp;
p=p->next;
}
}
temp=head->next;
i=1;
while(temp!=NULL)
{
printf("第%d個學生的姓名是:%s,學號是:%s\n",i++,temp->name,temp->number);
temp=temp->next;
}
}
system("pause");
return 0;
}
就是一個錄入n個學生的資訊的過程,滿心歡喜的運行,結果卻讓我很蛋疼,就是在運行過程中第一次輸入學生姓名的步驟總是被跳過了,
百思不得其解,上網查了一下,結果是因為在輸入學生個數的時候,敲的分行符號留在了輸入緩衝區裡面,而gets函數正是從緩衝區裡面讀取資料,並且是讀到分行符號作為本次輸入的結束,所以第一次運行到gets函數的時候直接從輸入緩衝區裡面讀入了分行符號,本次輸入結束,為了避免這種情況,可以在迴圈之前清空輸入緩衝區,可以使用getchar函數,getchar函數同gets函數類似,也是從輸入緩衝區中讀取資料,這樣相當於getchar把緩衝區中的分行符號取走了,也就是清空了輸入緩衝區,也可以使用fflush(stdin); 作用相同,也是清空輸入緩衝區,這裡不能使用getch函數,getch函數並不直接從緩衝區中讀取資料,而是等待使用者鍵盤輸入,直到使用者敲擊鍵盤為止,而分行符號依舊留在緩衝區中。
其實說getchar函數清空緩衝區是不對的,應該是從緩衝區中取走一個字元,恰好剛才的情況輸入緩衝區中只有一個字元。
這裡面還有一個問題,就是gets函數是不進行溢出檢查的,當我將name和number兩個字元數組的長度都設定為2後,發生了不可預知的情況,
輸出字串都超出了字元數組的長度,查看了一下name和number的地址,分別是4074544和4074546,也就是說在輸入姓名的時候順便把學號的記憶體也給寫了,而輸入學號的時候將多餘的字元寫到了相鄰的記憶體裡面。
怪不得人說gets函數只適用於玩具程式,呵呵。