Scanf vào nhưng printf không in ra được?

Moi người xem em sai chỗ nào nhập được nhưng không in ra được :frowning:

#include <stdio.h>
#include <stdlib.h>
struct thongtin
{
	int mssv;
	char hoten;
	float diem;
	char hanhkiem;
};
int main(int argc, char *argv[])
{
	int i,n;
	struct thongtin sinhvien[100];
	printf("Nhap so luong sinh vien:");
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		printf("Nhap thong tin sinh vien %d:\n",i);
		printf("Ma so sinh vien:");
		fflush(stdin);
		scanf("%d",&sinhvien[i].mssv);
		printf("Ho va ten:");
		scanf("%s",&sinhvien[i].hoten);
		fflush(stdin);
		printf("Diem trung binh:");
		scanf("%f",&sinhvien[i].diem);
		printf("Hanh kiem:");
		scanf("%s",&sinhvien[i].hanhkiem);
	}
	printf("Danh sach sinh vien:\n");
	printf("STT  MSSV\tHo va ten\t\tDiem\tHanh kiem");
	for(i=1;i<n;i++)
	{
		printf("%d  %d\t%s\t\t%f\t%s",i,sinhvien[i].hoten,sinhvien[i].diem,sinhvien[i].hanhkiem);
	}
	return 0;
}

Đây là một ký tự chứ không phải là mảng. @trungkiet_nguyen xem lại phần định nghĩa cho mảng nhé.

1 Like

char hoten[30];
char hanhkiem[10] chẳng hạn.
dòng printf cuối cũng có vấn đề

dạ em sửa lại được roi,cám ơn anh :smiley: em nhầm tý
printf cuối có vấn đề gì anh @david15894
mình có cách nào in ra cho mấy cái đó đứng đúng cột không anh

Dùng \t để tab ra cho nó đúng cột thử?

nhưng nếu chuỗi mình nhập zo dài hơn cái chuỗi trước thì nó nhảy không đúng sao anh

Canh tab nhiều vào :smiley:

1 Like

à,anh cho em hỏi thêm là đôi lúc em nhập dữ liệu thì nó lại bỏ qua 1 cái thông tin,ví dụ như em nhập mssv,nó bỏ qua tên luôn nhảy xuống điểm luôn,có cách nào khắc phục triệt để không anh ,em xai fflush(stdin) roi nhung cũng có khi vẫn bị

Do nó dính cái phím enter lúc em enter mssv đấy, em đặt fflush(stdin) vào trước cái dòng nhập tên thử? Mà anh nghĩ em không nên dùng scanf để nhập vào chuỗi, nên dùng fgets.

Em search fgets trong forum mình nhé. Gõ / rỗi điền vào fgets
Search thêm fflush luôn.

1 Like

nếu mình xài fgets thì khỏi cần xài fflush(stdin) ở ngoai phai ko anh

Cái này anh phải thú nhận là anh ít dùng, hoặc anh ít gặp lỗi liên quan đến stream nên anh không chắc. Nhưng cái anh chắc là nếu dùng fgets để nhập chuỗi thì an toàn và ổn định hơn scanf. Lý do là fgets hỗ trợ số lượng phần tử nhập vào, cho phép mình nhập khoảng trắng. scanf dễ dùng với nhập số hơn. Mặc dù cũng có cách để nhập chuỗi có khoảng trắng với scanf nhưng anh thấy không hay, không cần thiết và phức tạp hóa vấn đề.

Em có thể edit code theo hướng đấy và share lại code. Tốt nhất là nên tạo topic khác liên quan đến fflush hơn là tiếp tục hỏi ở đây :slight_smile:

printf("Ma so sinh vien:");
scanf("%d",&sinhvien[i].mssv);
//fflush(stdin);

chỗ này nhập số xài scanf nhưng nếu em khong xài fflush(stdin) thì nó van bị nhảy nè anh

Em tạo topic khác, post toàn bộ code lên hỏi về vấn đề fflush đi.

Để in đúng cột bạn có thể

printf("%-2d %-30s%-3f%-15s",i,sinhvien[i].hoten,sinhvien[i].diem,sinhvien[i].hanhkiem);

Dấu trừ ở để căn lề trái còn nếu bạn muốn căn lề phải thì bỏ dấu trừ đi bạn có thể thử để xem sự khác biệt

Ngoài ra ở chỗ chỗ khai báo struct bạn phải khai báo char hoten[30]; char hanhkiem[10]; vì nó là kiểu string

Ở chỗ scanf bạn cũng mắc lỗi

scanf("%s", sinhvien[i].hoten);
scanf("%s",sinhvien[i].hanhkiem);

Do sinhvien[i].hotenstring nên không cần dấu &sinhvien[i].hoten

bạn thử xem chương trình này xem mình test cho bạn xem

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

int main()
{
  char name[10];
  char hanhkiem[5];

  printf("nhap ten: ");
  fgets(name,5,stdin);
  printf("nhap hanh kiem: ");
  fgets(hanhkiem,3,stdin);
  printf("name = %s\n",name);
  printf("hanh kiem %s\n",hanhkiem);
  return 0;
  
}

fgets có điểm mạnh là nó giới hạn kích thước chuỗi nhập vào, ở ví dụ trên mình dùng

printf("nhap ten: ");
fgets(name,5,stdin);

trường hợp bạn nhập vào một chuỗi có độ dài lớn hơn so với chỉ số 5 trong fgets(name,5,stdin)
nếu bạn nhập vào một chuỗi chẳng hạn là 12345678 (thực ra k có ai tên thế này nhưng mình nhập như thế để cho bạn thấy rõ số kí tự fgets sẽ lấy) thì fgets sẽ chỉ lấy đúng 4 kí tự 1234 từ chuỗi 12345678 do chuỗi luôn kết thúc với ‘\0’ nên nó chỉ lấy 4 kí tự từ chuỗi.

một điểm nữa là fgets chỉ lấy 4 kí tự từ chuỗi 12345678 nên sẽ bị thừa ra chuỗi 5678 thì chuỗi này sẽ bị lưu vào buffer và chạy xuống câu fgets tiếp theo

fgets(hanhkiem,3,stdin);

và in ra kết qủa là hanhkiem là 56 luôn.

vì vậy bạn cần phải sử dụng fflush(stdin) ngay sau câu lệnh fgets thứ nhất

trường hợp bạn nhập vào một chuỗi nhỏ hơn chỉ số 5 trong fgets(name,5.stdin)
nếu bạn nhập vào chuỗi 12 và nhấn enter thì fgets sẽ lấy luôn dấu enter ném vào chuỗi name như thế bạn sẽ không cần dùng fflush(stdin).

Bạn có thể copy đoạn code trên về test thử sẽ rõ chứ mình sợ khả năng giải thích kém bạn khó hiểu

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