Hỏi về câu lệnh fflush(stdin) trong c

cô giáo mình bảo lệnh này để xóa bộ nhớ đệm trong c à
mình có một đoạn code như sau à

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
typedef struct
{
char name[30];
int diem;
}sv;
sv sinhvien[5];
char c[30];
for(int i=0;i<5;i++)
{
printf("moi ban nhap ten cua sinh vien thu %d:",i+1); 
gets(sinhvien[i].name);
printf("moi nhap diem cua sinh vien nha:");
scanf("%d",&sinhvien[i].diem);
}

đoạn code này chạy không hề ổn một tọe nào cả nó chỉ thực hiện vòng lặp thứ 1 đến vòng thứ 2 là tòe luôn à (minh họa sẽ bằng hình ảnh sau)
còn đây là đoạn code thứ 2 nó chỉ thêm mỗi lênh này thôi là lại ok à vậy tại sao khi có lệnh này nó lại chạy ổn
đây là đoạn code thứ 2 à

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
typedef struct
{
char name[30];
int diem;
}sv;
sv sinhvien[5];
char c[30];
for(int i=0;i<5;i++)
{
printf("moi ban nhap ten cua sinh vien thu %d:",i+1);
 fflush(stdin);
gets(sinhvien[i].name);
printf("moi nhap diem cua sinh vien nha:");
scanf("%d",&sinhvien[i].diem);
}
}

mong các bác chỉ giáo thêm

1 Like

Khi nhập xâu thì kết thúc bằng một ký tự xuống dòng ‘\n’. Nhưng compiler vẫn nhận đây là một xâu cho tới bộ nhớ tạm thời và truyền nó vào biến xâu tiếp theo của chương trình.
fflush(stdin); với mục đích xóa đi bộ nhớ tạm thời của chương trình để không tồn tại những giá trị rác như bên trên.
Nhưng về bản chất thì nên dùng cin.ignore(100,'\n');

1 Like

nhưng nếu không có đoạn code này phía dưới thì nó vẫn chạy bình thường @TheSky

printf("moi nhap diem cua sinh vien nha:");
scanf("%d",&sinhvien[i].diem);
1 Like

Ngay phía trên là nhập một xâu và kết thúc là một kí tự enter thì nó vẫn truyền vào biến nhận giá trị đằng sau.
diem kiểu giá trị khác với kí tự nên khi nhận giá trị sẽ báo lỗi.
thêm một đoạn

printf("moi nhap diem cua sinh vien nha:");
 fflush(stdin);
scanf("%d",&sinhvien[i].diem);
1 Like

0[quote=“Jobs_Apple_Steve, post:1, topic:25479”]

for(int i=0;i<5;i++) {
     printf("moi ban nhap ten cua sinh vien thu %d:",i+1); 
     gets(sinhvien[i].name);
     printf("moi nhap diem cua sinh vien nha:");
     scanf("%d",&sinhvien[i].diem);
}

[/quote]
Khi i = 0 : vẫn chạy bình thường, nhưng hàm scanf() chỉ lấy số điểm và không nhảy xuống hàng mới. Con trỏ lúc này nó chỉ vào ngay sau cái số đó. => lần kế tiếp gets() sẽ get những khoảng trống => abort trap

Giải pháp: fflush(stdin) có nghĩa là dọn dẹp sạch cái stdin, ko còn cái gì ở đó nữa, lúc này tên mà bạn nhập vào sẽ đc lấy.

Mình muốn hỏi bạn là tại sao bạn ko sử dụng char* name vì char name[30] rất là nguy hiểm…

2 Likes

tai sao char name[30]
lai nguy hiem ha ban

Bạn thử tưởng tượng khi 1 ai đó nhập tên của họ lớn hơn 30 kí tự thì sẽ như thế nào ? (Buffer Overflow). Và nếu như mình phải nhập điểm cho 10000 người thì mỗi người chiếm 30 Bytes cho phần tên là khá nhiều, với calloc thì bạn có thể tiết kiệm hơn tuỳ vào độ dài tên của họ :smiley:

1 Like

y anh la dung cáp phát động á

Yes, nếu bạn dùng cấp phát động thì cô giáo sẽ vui hơn rất nhiều :smiley:

1 Like

malloc voi calooc khac nhau cho nao nhi ma anh dang hoc o dau the anh

malloc thì cần phải tính toán vùng nhớ trước rồi mới truyền vào cho malloc.
calloc thì không cần nó tự tính luôn.
malloc nhanh hơn calloc vì calloc cần thời gian gán giá trị cho vùng nhớ nó vừa cấp.
tùy th mà sử dụng thôi :blush: lưu ý malloc có nhiều giá trị rác lắm nhé.

chang nhe lai hoi ho xem ten cua ho dai bao nhieu tu ha ban

Uhm, mình cũng thắc mắc như bạn @Jobs_Apple_Steve Jobs_Apple_Steve , mình biết dùng mỗi malloc thôi, mà malloc phải biết kích thước mảng để cấp phát nên không biết cấp phát như thế nào nhỉ :grin:

Dùng calloc nó sẽ tự cấp phát ô nhớ cho đối tượng luôn chỉ cần khai báo thôi :v

@auphuocnguyen Uầy, hay vậy, trước giờ mình toàn dùng malloc, ngu quá, phải xem lại mới được :sob:

tùy TH mà dùng bạn ơi :joy: chứ không phải bài nào mình cũng dùng calloc được :v:

1 Like

Ko cần :blush:
dùng fgets(char * str, int limit, FILE * stream) là ok
Như bạn chỉnh cần sửa lại thành
fgets(name, 30, stdin); là an toàn rồi

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