Dùng C đọc dữ liệu từ file lên bị lỗi?
Em có một bài tập, đề bài như sau ạ:
Lập trình thực hiện các nhiệm vụ sau
- Định nghĩa một kiểu cấu trúc Sinhvien gồm
- dtb (điểm trung bình theo thang 4.0 - kiểu float)
- masv, hoten là kiểu xâu kí tự
typedef struct
{
char masv[7];
char hoten[32];
float dtb;
} Sinhvien;
- Định nghĩa một kiểu cấu trúc Lop gồm có:
- dssv là một mảng con trỏ cấu trúc Sinhvien*
- siso là số sinh viên trong danh sách
const int MAX = 80;
typedef struct
{
Sinhvien dssv[MAX];
char tenlop[8];
int n;
} Lop;
- Đầu vào của chương trình là tệp SV.inp có định dạng như sau
Dòng 1: tên lớp
Dòng 2: sĩ số
- Các dòng tiếp theo: Mã số SV, họ tên, điểm trung bình
56PM
65
484756
Nguyen Van Hung
3.3
…
Lập chương trình bao gồm các hàm sau
a. Hàm nhập thông tin từ tệp tin vào một biến cấu trúc Lop gồm: tên lớp, sĩ số n, và thông tin của n sinh viên vào trong danh sách sinh viên . Với mỗi sinh viên cần nhập đầy đủ thông tin như: mã số, họ tên, điểm trung bình
void nhap_dssv (Lop* lop);
// tham số lop là đại diện cho địa chỉ của 1 biến cấu trúc sẽ lưu thông tin
b. Hàm sắp xếp danh sách sinh viên theo thứ tự điểm trung bình giảm dần
void sapxep_dssv(Sinhvien ds[], int n);
c. Hàm in danh sách sinh viên theo quy cách sau:
Ma so SV | Ho ten | Diem trung binh
374754 Nguyen Van Tuan 3.5
…
void in_dssv(Sinhvien ds[], int n);
d. Hàm tìm kiếm trong lớp và cho kết quả là một danh sách sinh viên có điểm trung bình lớn hơn d (0 <= d <= 4.0)
void tim_diemtb(Lop* lop, float d, Sinhvien ketqua[])
e. Viết hàm main thực thi việc
i. Nhập thông tin và danh sách sinh viên của lớp
ii. Sắp xếp danh sách sinh viên trong lớp và in ra màn hình
iii. Tìm kiếm sinh viên có điểm trung bình > 2.0 và in ra tệp SV.out theo định dạng trong câu c.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define MAX 80
struct SinhVien
{
char maSV[8];
char hoTen[50];
float dtb;
};
struct LopHoc
{
int siso;
SinhVien sv[MAX];
char tenLop[8];
};
void in_dssv(SinhVien ds[], int n)
{
printf("%-8s%-25s%-4s"," MSSV"," Ho ten"," Diem trung binh
");
for(int i=0; i<n; i++)
printf("%-8s%-25s%-3.2f
",ds[i].maSV,ds[i].hoTen,ds[i].dtb);
}
void nhap_dssv(LopHoc* lop)
{
FILE *f=fopen("SV.inp","r");
if(f==NULL)
{
perror("Loi mo tep SV.inp");
exit(1);
}
fflush(f);
fgets(lop->tenLop,10,f);
fscanf(f,"%d",&lop->siso);
for(int i=0; i<lop->siso; i++)
{
fgets(lop->sv[i].maSV,10,f);
fgets(lop->sv[i].hoTen,50,f);
fscanf(f,"%f",&lop->sv[i].dtb);
}
fclose(f);
}
void sapxep_dssv(SinhVien ds[], int n)
{
for(int i=0; i<n-1; i++)
for(int j=i+1; j<n; j++)
if(ds[i].dtb<ds[j].dtb)
{
struct SinhVien tg=ds[i];
ds[i]=ds[j];
ds[j]=tg;
}
printf("
Danh sach sau khi sap xep:
");
in_dssv(ds,n);
}
void tim_diemtb (LopHoc* lop, float d, SinhVien ketqua[])
{
int m=0;
for(int i=0; i<lop->siso; i++)
if(lop->sv[i].dtb>d)
{
ketqua[m]=lop->sv[i];
m++;
}
FILE *f=fopen("SV.out","w");
if(f==NULL)
{
perror("Loi mo tep SV.out");
exit(1);
}
if(m>0)
{
fprintf(f,"%-8s%-25s%-4s"," MSSV"," Ho ten"," Diem trung binh
");
for(int i=0; i<m; i++)
fprintf(f,"%-8s%-25s%-3.2f
",ketqua[i].maSV,ketqua[i].hoTen,ketqua[i].dtb);
fclose(f);
}
else fprintf(f,"Khong co sinh vien nao co dtb>%3.1f
",d);
}
int main()
{
LopHoc* lop=(LopHoc*) malloc(sizeof(LopHoc));
SinhVien kq[MAX];
nhap_dssv(lop);
sapxep_dssv(lop->sv,lop->siso);
tim_diemtb(lop,2.0,kq);
free(lop);
getch();
return 0;
}
Trên đây là chương trình e viết, chạy không lỗi nhưng kết quả cứ sai tùm lum hết. T.T
anh chị nào có kinh nghiệm làm việc với file thì giúp e chỉnh sửa với đc ko ạ.
Em cảm ơn ạ.
I moved a post to a new topic: Ghép nội dung của 2 files sinh ra ký tự lạ ở file thứ 2?
Em chỉ ra sai cụ thể chỗ nào, anh sẽ xem cho. Giống như bài này, em đặt câu hỏi rất cụ thể. Là có ký tự lạ ở cuối file đích. Anh đọc hiểu ngay.
A thử copy code trên rồi chạy ví dụ với file SV.inp như sau ạ:
chứ e ko biết miêu tả lỗi như nào cả. T.T
Tối hoặc mai nhé, đang bận tí việc…
vâng ạ.
e cũng đang học môn khác.
gần cuối kì rồi thi với kiểm tra dồn dập quá ạ. T.T
a ơi, xem giúp e với. T.T
Cụ thể hợp đi @htwap, anh bận quá, anh có chạy thử rồi, thấy in ra lung tung mà không có thời gian kiểm tra xem em viết cái gì
e cũng ko biết bị lỗi gì nữa a ạ, nêu nhập từ bàn phím thì ngon lành, e nghĩ chắc là sai chỗ lấy dữ liệu từ file ạ
Em không hiểu lỗi gì mà bắt anh sửa, , nếu anh có thời gian thì anh sẽ tra dùm em. Nhưng anh bận quá, em chỉ ra lỗi cụ thể anh sửa trong 30s thì được
bị sai chỗ lấy dữ liệu từ file a ạ, tại sai chỗ đấy nên các bước sau sai hết.
e ko biết lấy sao cho đúng. T.T
Sai như thế nào em.
Input như thế nào? Em muốn lấy như thế nào và nó trả ra như thế nào?
e input gồm:
+dòng đầu là số n chỉ số sinh viên
+các dòng tiếp theo cho 3 thông tin của mỗi sinh viên là mã số sinh viên, họ tên, điểm trung bình.
ví dụ:
là 2 sinh viên Sáng Còi và Dạy Nhau Học.
e muốn lấy thông tin cho vào biến cấu trúc Lop gồm 2 sinh viên đó và mỗi sinh viên lại là cấu trúc gồm Mã sinh viên, họ tên và điểm.
Yêu cầu in ra:
úp úp.
e sửa mấy ngày rồi ko đc ạ.
Vẫn code cũ luôn hả @htwap?
1.Lỗi sai kích thước
Giải pháp: #define vài cái macro để xài
Sau đó đọc vào như sau
2.Sai cấu trúc nhập vào
Em nhập vào sai rôi, em bảo cấu trúc là
Mà vô một phát em đọc tên lớp, đâu có tên lớp đâu mà đọc?
3.Struct em đâu thể gán như số int mà em phải viết hàm swap như sau
4.Không thể dùng fgets để đọc từng dòng, em phải viết hàm đọc từng dòng.
Anh đã viết ở đây, em phải đọc cho hiểu mới được xài.
Em xem lại code anh sửa tới hàm nhập, hàm sắp xếp em tự kiểm tra lại
sao struct e vẫn gán thẳng dc mà a @@
Yeah, vì em may mắn là struct của em đơn giản, không có con trỏ. Có mảng, nhưng là mảng tĩnh. Nên việc copy tương tự như copy memory. Nhưng nếu em sử dụng con trỏ
char * ho_ten;
thì việc gán như vậy không đảm bảo.vâng, e sẽ lưu ý ạ.
thank a nha
I moved 2 posts to a new topic: Dùng hàm gì để đổi ký tự trong C++?