Lỗi khi chạy chương trình quản lý sinh viên bằng C

Dạ chào mọi người, em thử code một chương trình quản lý sinh viên đơn giản chỉ nhập/xuất thông tin sinh viên thôi, nhưng em không hiểu tại sao khi chạy thì chương trình thì lúc xuất tên của sinh viên cuối cùng trong mảng thì bị lỗi. Đây là code của em:

struct SinhVien{
	char tenSV[30];
	char maSV[10];
	char lop[5];
	int tuoi;
};
void nhap(int siso){
	struct SinhVien dsSV[siso];
	int i;
	for(i=0;i<siso;i++)
	{
		printf("Nhap thong tin sinh vien thu %d\n",i+1);
		printf("Nhap ten sinh vien thu %d:",i+1);
		fflush(stdin);
		gets(dsSV[i].tenSV);	
	}
}
void xuat(int siso){
	int i;
	struct SinhVien dsSV[siso];
	for(i=0;i<siso;i++)
	{
		printf("Ten sinh vien thu %i la:\t",i+1);
		printf("%s\n",dsSV[i].tenSV); 	
	}
}
int main()
{
	int siso;
	printf("Nhap vao so luong sinh vien:");
	scanf("%d",&siso);
	nhap(siso);
	xuat(siso);
}

Mọi người có thể chỉ giúp xem em sai chỗ nào không ạ? Cảm ơn

Vấn đề của bạn ở hàm nhap() và hàm xuat().
Theo trình tự chương trình thì khi vào hàm nhap() nó sẽ tạo ra một array dsSV rồi bạn nhập thông tin cho cái array này, cuối hàm nhap() thì nó sẽ tự động bị xóa đi. (Vì dsSV chỉ là biết cục bộ).
Rồi đến hàm xuat() nó lại tạo ra một array khác nhưng vẫn tên là dsSV nhưng cái này khác hoàn toàn với cái bạn đã tạo trước đó trong hàm nhap(). Và thế là bạn in ra thông tin từ cái array mà bạn mới tạo.


Giải pháp cho bạn thì có một vài cách đơn giản sau đây:

  • Sửa lại hàm nhap(int siso)xuat(int siso) thành nhap(struct SinhVien *dsSV, int siso)xuat(struct SinhVien *dsSV, int siso) rồi truyền một cái dsSV mà bạn phải tạo ở main() trước đó.

  • Bỏ hết dòng struct SinhVien dsSV[siso] trong 2 hàm nhap()xuat() rồi đưa ra ngoài (để ngay dưới struct SinhVien {..};) mục đích là cho cái dsSV thành biến toàn cục.


Code sửa cho bạn.

struct SinhVien{
	char tenSV[30];
	char maSV[10];
	char lop[5];
	int tuoi;
};
void nhap(struct SinhVien *dsSV, int siso){
	int i;
	for(i=0;i<siso;i++)
	{
		printf("Nhap thong tin sinh vien thu %d\n",i+1);
		printf("Nhap ten sinh vien thu %d:",i+1);
		fflush(stdin);
		gets(dsSV[i].tenSV);	
	}
}
void xuat(struct SinhVien *dsSV, int siso){
	int i;
	for(i=0;i<siso;i++)
	{
		printf("Ten sinh vien thu %i la:\t",i+1);
		printf("%s\n",dsSV[i].tenSV); 	
	}
}
int main()
{
	int siso;
	printf("Nhap vao so luong sinh vien:");
	scanf("%d",&siso);
	struct SinhVien dsSV[siso];
	nhap(dsSV, siso);
	xuat(dsSV, siso);
}
3 Likes

Phải là fflush(stdout).

stdin đúng r mà đại ca. :sweat_smile:

1 Like

Tại sao fflush(stdin) không đúng:


Tại sao lại là fflush(stdout)? Xem link dưới:

https://codeforces.com/blog/entry/45307

2 Likes

Chỉ là do fflush(stdin) chỉ hoạt động tốt trên windows và e thấy tốt nhất trên code::blocks, VS Code cũng tạm. Với lại fflush(stdin) không thuộc thư viện chuẩn nên k được khuyên dùng thôi. Nhưng dùng stdout thì k có tác dụng.

Đây là khi e sd fflush(stdin).
image

Còn fflush(stdout) thì :sweat_smile:
image


Với lại đây là trong C, chứ k phải C++, nên fflush(stdin) vẫn hoạt động khá tốt.

1 Like

Quên mất điều này. Khi scanf("%d",&siso); thì trong input buffer còn dư kí tự xuống dòng, kí tự này sẽ bị đẩy xuống input tên sinh viên đầu tiên -> trôi lệnh. Thêm getchar() sau scanf() là được.

Đã fflush(stdout) thì buffer input và output không bị chồng chéo, cũng như việc không in ra các dòng mời mọc Nhập số ... và chỉ input data.

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?