30/09/2018, 18:12

Đoạn code khó hiểu về con trỏ FILE trong C

Em có đoạn code về chương trình làm danh bạ trong C
Yêu cầu:

nhập file theo cấu trúc đã cho sẵn ( các bác đọc code là hiểu ngay) - danh sách lưu vào file list.txt. - mở lại chương trình vẫn có thể nhập thêm dữ liệu cho file

code đây ạ

#include <stdio.h>
#include <stdlib.h>
typedef struct danhba {
    char name[20];
    char telephone[20];
    char mail[20];
} list;
FILE *f;
list a[100];
void nhapdanhsach(int* n) {
    int i,t;
    if((f = fopen("list.txt", "w")) == NULL) {
        printf("Khong the mo file!
");
        exit(0);
    }
    printf(" nhap them so nguoi ban muon 
");
    scanf("%d",&t);
    printf("ok- ban se nhap them %d nguoi 
",t);
    *n=*n+t;
    __fpurge(stdin);
    for(i = *n-t; i <*n; i++) {
        printf("Nhap vao nguoi thu %d :
 ", i + 1);
        __fpurge(stdin);
        printf("Nhap vao ho ten: 
");
        gets(a[i].name);
        __fpurge(stdin);
        printf("Nhap vao sdt: 
");
        gets(a[i].telephone);
        __fpurge(stdin);
        printf("Nhap vao ho mail: 
 ");
        gets(a[i].mail);
        __fpurge(stdin);
        fwrite(&a[i], sizeof(list), 1, f);
    }
};
void   xemdanhsach(FILE *f,int *n) {
    int i;
    f = fopen("list.txt", "rb");
//doc so nhan vien
    fseek(f,0,SEEK_END);
    printf("n= %d 
",n);
    for(i = 0; i <*n ; i++) {
        fread(&a[i], sizeof(list), 1, f);
        printf("%s %s %s
", a[i].name, a[i].telephone,a[i].mail);
    }
    fclose(f);
};
int main() {
    int n=0;
    char c;
    if(f = fopen("list.txt", "r")) {
        fseek(f,0,2);
        n=ftell(f)/sizeof(list);
        printf("n=%d 
 ",n);
        rewind(f);
        fread(a, sizeof(list), n, f);
        fclose(f);
    }
    while(1) {
        printf("------------------------------------------
");
        printf("      Da co %d nguoi trong danh ba
",n);
        printf("          1.Nhap them danh ba
");
        printf("          2.Xem danh ba
");
        printf("          3.Thoat
");
        printf("          Moi ban nhap: 
");
        __fpurge(stdin);
        scanf("%c",&c);
        __fpurge(stdin);
        if(c=='1') nhapdanhsach(&n);
        else if (c=='2') xemdanhsach(f,&n);
        else if (c=='3') break;
        else printf("ban da nhap sai-moi nhap lai
");
    }
    return 0;
}

Vấn đề em gặp phải:

1.Tại sao em khai báo là

f = fopen("list.txt", "w")

nó vẫn không bị ghi đè mà nó vẫn ghi tiếp?

2.Chương trình phải thoát bằng cách nhấn phím 3 (vì nó sẽ đưa đến câu lệnh break để thoát chương trình) thì nó mới lưu dữ liệu vào file còn nếu thoát bằng cách dùng phím ( X ) trong terminal thì không lưu đc

3.Tại sao nó chạy đúng trong 2 lần mở- đóng chạy chương trình đầu tiên. Còn lại thì nó chỉ lưu 2 phần tử cuối cùng?

các bác xem ảnh là hiểu nhé : xem đến ảnh 3 là các bác hiểu

Ảnh 1

Ảnh 2

Ảnh 3 :vấn đề ở đây đây

Mai Anh Dũng viết 20:16 ngày 30/09/2018

1.Tại sao em khai báo là

f = fopen(“list.txt”, “w”)

nó vẫn không bị ghi đè mà nó vẫn ghi tiếp?

Tại sao bạn lại chắn chắn như thế?

Huỳnh Đức viết 20:27 ngày 30/09/2018

em đọc trong các slide ạ ?
nó bảo là “w” là chế độ tạo file mới để ghi hoặc ghi đè

nếu ko phải vậy thì ntn ạ ?

Mai Anh Dũng viết 20:14 ngày 30/09/2018

nó bảo là “w” là chế độ tạo file mới để ghi hoặc ghi đè

Cái này thì đúng rồi, ý Đạt là tại sao bạn chắc chắn là nó vẫn không bị ghi đè mà nó vẫn ghi tiếp?

Huỳnh Đức viết 20:21 ngày 30/09/2018

dạ em chạy chương trình thấy nó ko bị ghi đè ạ ?
anh giúp e với ? e cũng không hiểu ạ

Mai Anh Dũng viết 20:24 ngày 30/09/2018

dạ em chạy chương trình thấy nó ko bị ghi đè ạ ?

Tức là em nhận định sai, vì “w” chắc chắn là tạo file mới. Em kiểm tra lại để kiểm chứng lại nhận định về việc nó không ghi đè mà vẫn ghi tiếp xem.

Xóa bỏ các đoạn code không cần thiết, tập trung vào chỗ ghi dữ liệu xuống thôi.

Huỳnh Đức viết 20:25 ngày 30/09/2018

em thử rồi mà ko tìm được ạ
em xóa rồi,đổi cả tên file mà sao nó vẫn nhận diện được ấy
debug thì con trỏ file nó chạy lung tung ấy ?

Mai Anh Dũng viết 20:24 ngày 30/09/2018

em xóa rồi,đổi cả tên file mà sao nó vẫn nhận diện được ấy

Gửi một chương trình ngắn gọn lên anh xem thử?

Huỳnh Đức viết 20:23 ngày 30/09/2018
#include <stdio.h>
#include <stdlib.h>
typedef struct danhba {
    char name[20];
    
} list;
FILE *f;
list a[10];
void nhapdanhsach(int* n) {
    int i,t;
    if((f = fopen("list.txt", "w")) == NULL) {
        printf("Khong the mo file!\n");
        exit(0);
    }
    printf(" nhap them so nguoi ban muon \n");
    scanf("%d",&t);
    printf("ok- ban se nhap them %d nguoi \n",t);
    *n=*n+t;
    __fpurge(stdin);
    for(i = *n-t; i <*n; i++) {
        printf("Nhap vao nguoi thu %d :\n ", i + 1);
        __fpurge(stdin);
        printf("Nhap vao ho ten: \n");
        gets(a[i].name);
        __fpurge(stdin);

        
        fwrite(&a[i], sizeof(list), 1, f);
    }
};
void   xemdanhsach(FILE *f,int *n) {
    int i;
    f = fopen("list.txt", "rb");
//doc so nhan vien
    fseek(f,0,SEEK_END);
    printf("n= %d \n",n);
    for(i = 0; i <*n ; i++) {
        fread(&a[i], sizeof(list), 1, f);
        printf("%s %s %s\n", a[i].name);
    }
    fclose(f);
};
int main() {
    int n=0;
    char c;
    if(f = fopen("list.txt", "r")) {
        fseek(f,0,2);
        n=ftell(f)/sizeof(list);
        printf("n=%d \n ",n);
        rewind(f);
        fread(a, sizeof(list), n, f);
        fclose(f);
    }
    while(1) {
        printf("------------------------------------------\n");
        printf("      Da co %d nguoi trong danh ba\n",n);
        printf("          1.Nhap them danh ba\n");
        printf("          2.Xem danh ba\n");
        printf("          3.Thoat\n");
        printf("          Moi ban nhap: \n");
         __fpurge(stdin);
        scanf("%c",&c);
        __fpurge(stdin);
        if(c=='1') nhapdanhsach(&n);
        else if (c=='2') xemdanhsach(f,&n);
        else if (c=='3') break;
        else printf("ban da nhap sai-moi nhap lai\n");
    }
    return 0;
}

em chi biet rut gon the nay thoi
anh xem giup em
em cho chay mot lan roi em doi ca ten file “list.txt” thanh “list1.txt” ma no van nhan dien duoc file a

Huỳnh Đức viết 20:20 ngày 30/09/2018

có ai giúp mình không ?

Mai Anh Dũng viết 20:17 ngày 30/09/2018

em chi biet rut gon the nay thoi anh xem giup emem cho chay mot lan roi em doi ca ten file “list.txt” thanh “list1.txt” ma no van nhan dien duoc file a

Em viết tiếng Việt có dấu đi


Em gửi mẫu nội dung em test dẫn đến nhận định là file không bị ghi đè lên? Anh vẫn chưa thấy lý do tại sao em lại cho rằng file không bị ghi đè

Huỳnh Đức viết 20:14 ngày 30/09/2018

em xin lỗi- lúc đó em đang code nên phải tắt ibus ạ

đây là code em test - em thêm hàm này để chạy xác nhận nó ghi đè ( và nó ghi đè thật ??? )
với yêu cầu test là nhập 3 người trước - sau đó nhập thêm 2 người nữa để test
với chế độ “w” thì nó sẽ ghi đè - thế nhưng kết quả là nó vẫn ghi tiếp và cho in ra 5 người anh ạ
em ko hiểu tại sao nữa
code hàm test đây

void   test(FILE *f,int *n)
    {
    int i;
    f = fopen("list.txt", "rb");

    fseek(f,0,SEEK_END); // dua con tro file ve cuoi

    for(i = 0; i <3 ; i++)
        {
        fread(&a[i], sizeof(list), 1, f);
        printf("%s %s %s\n", a[i].name, a[i].telephone,a[i].mail);
        }
    fclose(f);
    if((f = fopen("list.txt", "wb")) == NULL) // ghi tiep vao file
        {
        printf("Khong the mo file!\n");
        exit(0);
        }

    printf("ok- ban se nhap them 2 nguoi nua de test \n");

    __fpurge(stdin);
    for(i = 3; i <5; i++)
        {
        printf("Nhap vao nguoi thu %d :\n ", i+1);
        __fpurge(stdin);
        printf("Nhap vao ho ten: \n");
        gets(a[i].name);
        __fpurge(stdin);
        printf("Nhap vao sdt: \n");
        gets(a[i].telephone);
        __fpurge(stdin);
        printf("Nhap vao ho mail: \n ");
        gets(a[i].mail);
        __fpurge(stdin);
        fwrite(&a[i], sizeof(list), 1, f);
        }
    // doc lai de xem file co ghi tiep hay khong
    f = fopen("list.txt", "rb");

    fseek(f,0,SEEK_END); // dua con tro file ve cuoi

    for(i = 0; i <5 ; i++)
        {
        fread(&a[i], sizeof(list), 1, f);
        printf("%s %s %s\n", a[i].name, a[i].telephone,a[i].mail);
        }
    fclose(f);
    };
Bài liên quan
0