Bài tập viết chương trình quản lí sinh viên bị lỗi ghi 1 sinh viên vào file 2 lần

Mọi người ơi cho em hỏi.Em đang làm bài tập viết chương trình quản lí sinh viên đến phần thêm sinh viên vào list thì bị lỗi như này:lúc tạo danh sách sinh viên thì vẫn bình thường,nhưng khi thêm 2 sinh viên trở lên là lại có 1 sinh viên được ghi 2 lần ạ :frowning:


Code hàm thêm sv đây ạ:

int sott;
struct{
char tensv[300];
int ngaysinh;
int thangsinh;
int namsinh;
int id;
};

void them(){
	
	int add;
	
	char ten[300];
	
	
	printf("\nSo sinh vien muon them : ");
	scanf("%d",&add);
	while(1){
	 
	 	
	 
	 if(add>0){
	int i=0;
    struct svdetails sv[add-1];
    int nam[add-1];
	int thang[add-1];
	int ngay[add-1];
	for(i;i<add;i++){
	printf("\nNhap ten sinh vien thu %d : ",i+1);
	fflush(stdin);
	gets(ten);
	
	printf("\nNam sinh: ");
	
	printf("\nNgay : ");
	while(1){
	if(scanf("%d",&ngay[i])==1){
	  if(ngay[i]<1||ngay[i]>31)printf("\nNgay sinh phai la tu 01-30\nNgay: ");
	  else if(ngay[i]>0&&ngay[i]<32)break;}}
    
    printf("\nThang: ");
    while(1){
	if(scanf("%d",&thang[i])==1){
	  if(thang[i]<1||thang[i]>12)printf("\nThang sinh phai la tu 01-12\nThang: ");
	  else if(thang[i]>0&&thang[i]<13)break;}}
	
	printf("\nNam : ");  
	while(1){
	if(scanf("%d",&nam[i])==1){
	  if(nam[i]<1950||nam[i]>2020)printf("\nNam sinh phai la tu 1950-2020\nNam: ");
	  else if(nam[i]>1949&&ngay[i]<2021)break;}}	
	
	strcpy(sv[i].tensv,ten);
	sv[i].ngaysinh=ngay[i];
	sv[i].thangsinh=thang[i];
	sv[i].namsinh=nam[i];
	
	if(1950<=sv[i].namsinh&&sv[i].namsinh<2000){
    	sv[i].id=1000000+ngay[i]+thang[i]+nam[i]+i+1;
	}
    else if(2000<=sv[i].namsinh&&sv[i].namsinh<=2020){
    	sv[i].id=2000000+ngay[i]+thang[i]+nam[i]+i+1;
	}
	
	FILE *ghi;
	ghi=fopen("data\\sinhvien.bin","ab");
	fwrite(&sv,sizeof(struct svdetails),i+1,ghi);
	fclose(ghi);
	
	
	
	sott=sott+i+1;
	FILE *stt;
	stt=fopen("data\\stt.txt","w");
	fprintf(stt,"%d",sott);
	fclose(stt);
	
	
}

	printf("da luu du lieu cua %i sinh vien",i);break;
}else if(add<1)printf("\nSo sinh vien it nhat la 1 !");them();
}


	printf("\nLua chon: ");
}

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

Nhìn hơi đau mắt với khoản thụt lề.
Vài lỗi:

  1. struct svdetails sv[add-1];... khai báo mảng kiểu gì đây? Số lượng phần tử!
  2. Sau khi gán giá trị cho sinh viên tại i (sv[i].ngaysinh=ngay[i];) thì ghi dữ liệu tại i + 1 (fwrite(&sv,sizeof(struct svdetails),i+1,ghi);).

Nếu nhập đến đâu, ghi đến đó thì chẳng cần dùng mảng làm gì.

5 Likes

Đến lúc đọc dữ liệu thì làm như thế nào ạ.E tưởng cái hàm fwrite() với fread() là đọc và ghi một mảng struct

Ơ ghi thế nào thì đọc thế đó. Trong đọc ghi file nhị phân thì dùng fread() để đọc. Nếu không thích thì nhập xuất file với format bằng fscanf() với fprintf() đi. Dùng kí tự đặc biệt nào đó để phân cách chứ dùng fwrite() và fread() phải xác định chính xác số lượng theo em thấy khá là mệt mỏi.

ID sao anh không random cho dễ lại xét điều kiện làm gì :pensive:.
Lí do lặp thì khả năng ở hàm xuất ra màn hình chứ không phải ở hàm thêm đâu. Anh debug thử đi. Giá mà đọc ghi file text thì mở file lên là biết sai ở đâu rồi :pensive:.

3 Likes

file nhị phân cũng mở được để xem mặc dù nó toàn kí tự tùm lum blah blah nhưng tên mình vẫn thấy đc,nó có bị lặp trong file.Nếu dùng hàm fscanf() thì để đọc chuỗi thì nó sẽ dừng lại khi gặp khoảng trắng.Cái ID em muốn nó có quy tắc với dễ nhớ nên ko dùng srand().Mà thực ra em mới lớp 11 đang tự học với anh hướng dẫn nên cũng có mấy chỗ hơi mơ hồ,thế nên em cũng chưa biết dùng debug :pensive:

Đồng ý là có thể nhìn thấy nố bị lặp nhưng em nghĩ nên ghi bằng file text vẫn hơn vì:

  • Mới học nên việc thao tác với file nhị phân chưa thật sự tốt khiến cho lúc kiểm soát nội dung trong file nhị phân là không thể.
  • Thao tác bằng file text anh có thể luyện thêm được ở phần định dạng nhập xuất

Cái này thì không hẳn. Anh có thể tìm hiểu theo từ khóa %20[^\n] là có thể giải quyết được. Không tìm được thì quay lại đây hỏi tiếp nhé.

Anh có người hướng dẫn đã là 1 lợi thế và đừng bao giờ đổ lỗi cho hoàn cảnh như vậy 1 lần nào nữa vì làm vậy thì không tiến bộ được đâu.

Có chỗ nào mơ hồ anh có thể lên đây hỏi. Mọi người rất vui khi được giúp đỡ anh :grin: . Miễn sao anh đừng nhờ giải bài tập hoặc không chịu search google là được.

Anh chịu khó search 1 chút nhé. Anh sử dụng text editor hay IDE để code. Nếu Text editor thì hơi mệt còn các IDE thì trên mạng có hướng dẫn rất nhiều. Search theo key cách debug code trên <tên IDE đang dùng> .

P/s 1 : Anh đọc góp ý của anh @SITUVN.gcd đi nhé.

sửa lại mấy cái thụt đầu dòng 1 tí. Mỏi mắt quá
int sott;
struct{
    char tensv[300];
    int ngaysinh;
    int thangsinh;
    int namsinh;
    int id;
};

void them(){

	int add;

	char ten[300];


	printf("\nSo sinh vien muon them : ");
	scanf("%d",&add);
	while(1){
        if(add>0){

            int i=0;
            struct svdetails sv[add-1];
            int nam[add-1];
            int thang[add-1];
            int ngay[add-1];

            for(i;i<add;i++){
                //Nhap ten
                printf("\nNhap ten sinh vien thu %d : ",i+1);
                fflush(stdin);
                gets(ten);

                printf("\nNam sinh: ");
                //Nhap ngay
                printf("\nNgay : ");
                while(1){
                    if(scanf("%d",&ngay[i])==1){

                        if(ngay[i]<1||ngay[i]>31) {
                            printf("\nNgay sinh phai la tu 01-30\nNgay: ");
                        }
                        else if(ngay[i]>0&&ngay[i]<32){
                            break;
                        }
                    }
                }
                //Nhap thang
                printf("\nThang: ");
                while(1){
                    if(scanf("%d",&thang[i])==1){
                        if(thang[i]<1||thang[i]>12){
                            printf("\nThang sinh phai la tu 01-12\nThang: ");
                        }
                        else if(thang[i]>0&&thang[i]<13){
                            break;
                        }
                    }
                }
                //Nhap nam
                printf("\nNam : ");
                while(1){
                    if(scanf("%d",&nam[i])==1){
                        if(nam[i]<1950||nam[i]>2020){

                            printf("\nNam sinh phai la tu 1950-2020\nNam: ");

                        }
                        else if(nam[i]>1949&&ngay[i]<2021){

                            break;

                        }
                    }
                }

                //copy info
                strcpy(sv[i].tensv,ten);
                sv[i].ngaysinh = ngay[i];
                sv[i].thangsinh = thang[i];
                sv[i].namsinh = nam[i];
                //Cal ID
                if(1950 <= sv[i].namsinh && sv[i].namsinh <2000){

                    sv[i].id = 1000000 + ngay[i] + thang[i] + nam[i] + i + 1;

                }
                else if(2000 <= sv[i].namsinh && sv[i].namsinh <= 2020){

                    sv[i].id = 2000000 + ngay[i] + thang[i] + nam[i] + i + 1;

                }
                //creat file ptr
                FILE *ghi;
                ghi = fopen("data\\sinhvien.bin","ab");
                //Ghi file
                fwrite(&sv,sizeof(struct svdetails),i+1,ghi);

                fclose(ghi);
                //Refresh STT
                sott=sott + i + 1;
                //Ghi STT
                FILE *stt;
                stt=fopen("data\\stt.txt","w");
                fprintf(stt,"%d",sott);
                fclose(stt);
            }

            printf("da luu du lieu cua %i sinh vien",i);
            break;
        }
        else if(add<1){
            printf("\nSo sinh vien it nhat la 1 !");
            them();
        }
    }

	printf("\nLua chon: ");
}

P/s 2 : Anh nên viết ngoặc nhọn sau mỗi câu lệnh điều kiện nhé. Làm vậy để sau này dễ sửa và cũng dễ nhìn hơn nhé.

2 Likes

Vâng e cảm ơn đóng góp của mọi người,em sẽ tìm hiểu thêm rồi hỏi mọi người tiếp ạ :sweat_smile:

1 Like

Anh bỏ tick solution reply của em nhé. Reply đó không giải quyết được vấn đề bị lặp của anh

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