Xử lý dữ liệu tệp văn bản - Lập trình C : Bài 18

Xử lý dữ liệu tệp văn bản - Lập trình C : Bài 18
access_time 10/17/2019 12:00:00 AM
person Đào Minh Giang

 

Xử lý dữ liệu tệp văn bản - Lập trình C : Bài 18

1. Giới thiệu

Dữ liệu file văn bản bao gồm một tập hợp các chuỗi ký tự và văn bản được tổ chức thành dòng. Mỗi dòng có độ dài khác nhau, số lượng lớn nhất các kí tự trong 1 dòng là 256 ký tự. Mỗi dòng được đánh dấu bởi ký tự kết thúc dòng hay dấu xuống dòng. Trong DOS đó là cặp ký tự điều khiển CR(Carriage Return: nhảy về đầu dòng , mã số ASCII = 13, ‘\r’) và LF (Line Feed : Nhảy thẳng xuống dòng tiếp theo, mã số ASC II = 10, ‘\n’). Khi lập trình C chỉ cần dùng ‘\n’ là đủ để cách 2 dòng.

Ví dụ đoạn văn bản sau:

Lap Trinh C

123

Ket Thuc

Khi đó nếu xét theo cấu trúc của file văn bản trong DOS sẽ như sau

Lap trinh C CR LF 123 CRLF Ket Thuc EOF

Khi lập trình C thì file *.c là một loại file văn bản được sử dụng để lưu trữ các đoạn mã chương trình C.

2. Làm việc với File văn bản

C cung cấp 4 hàm sau đây để thực hiện đọc file văn bản.

+ fscanf()

+ fgets()

+ fgetc()

+ fread()

Với thao tác ghi file văn bản. C cung cấp 4 hàm sau

+ fprintf()

+ fputs()

+ fputc()

+ fwrite()

2.1 Hàm putc và puts.

2.1.1 Hàm putc()

Hàm putc thực hiện ghi một ký tự vào một luồn dữ liệu gắn với file. Nếu nói một cách đơn giản thì nó thực hiện việc ghi dữ liệu một character vào một file.

Cú pháp:

int putc(int ch, FILE *fp);

Mô tả :

+ ch: là ký tự muốn ghi vào trong file

+ fp: con trỏ trỏ đến File

giá trị trả về hàm putc:

+ Nếu không lỗi thì trả về chính là ch.

+ Nếu có lỗi : trả về EOF (Có giá trị là 0).

Code minh họa


Hình số 1 : Ví dụ về sử dụng hàm fputc

Khi chạy chương trình kết quả sẽ ghi dữ liệu ra file file.txt như sau

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd

2.1.2 Hàm puts()

Vai trò của hàm puts là ghi xâu kí tự (string) vào luồng dữ liệu, luồng dữ liệu này ghắn kết với file. Kết quả hàm thực hiện ghi xâu ký tự vào trong file này.

Cú pháp

char fputs(char *str, FILE *fp);

str : con trỏ kiểu char, bản chất nó chính xâu ký tự

fp: con trỏ file

Hàm trả về một giá trị không âm nếu quá trình ghi file thành công

Nếu lỗi hàm sẽ trả về EOF (Có giá trị 0).

Ví dụ


Hình số 2 : Ví dụ về sử dụng hàm fputs

Hàm thực hiện ghi 2 dòng “Ngon ngu lap trinh C” và “Lam viec voi file Van Ban” vào file.txt. vì sử dụng fopen(“file.txt”,”w+”) do vậy nếu file.txt đã tồn tại thì thực hiện xóa file này và tạo mới file. Ngược lại nếu chưa có file.txt thì sẽ tiến hành tạo mới file.txt.

Khi sử dụng fputs(“Ngon ngu Lap trinh C .\n”,fp); thì sẽ ghi xây ký tự “Ngon ngu Lap trinh C” vào file. Kêt thúc dòng này là thực hiện xuống dòng.

Vậy khi đó dữ liệu sẽ được ghi vào file.txt trên 2 dòng riêng biệt.

2.2 Kết thúc file (EOF – End of File)

Khi thực hiện đọc file, làm thế nào để xác định được quá trình đọc là kết thúc. Có một cách là dựa vào kí tự đặc biệt để đánh dấu kết thúc file.

Ví dụ

+ Kí tự # được đặt để xác định dòng cuối cùng

+ Trong DOS sử dụng Ctr-z như là một ký tự đặc biệt để xác định kết thúc file.

+ Trong UNIX sử dụng Ctr-d như là một ký tự đặc biệt để xác định kết thúc file.

Xác định kết thúc file

Đôi khi không biết chính xác mất thời gian bao lâu để đọc dữ liệu của một file tính từ thời điểm bắt đầu tiến trình đọc file đến khi kết thúc tiến trình đọc file.

Có 2 cách để xác định kết thúc một file, khi đọc dữ liệu file văn bản, quá trình xử lý sẽ đọc từng kí tự một, khi đó lập trình viên có thể đọc được kí tự đánh dấu kết thúc file.

Các hằng số biểu tượng EOF được định nghĩa trong stdio.h có giá trị là -1. Khi thực hiện các hàm đọc dữ liệu file văn bản theo cách thức đọc từng kí tự, thì quá trình đọc được thực hiện cho đến khi gặp kí tự đánh dấu kết thúc file.

Vì ở đây quá trình đọc được thực hiện cho đến khi gặp kí tự đánh dấu kết thúc file nên các lập trình viên thường sử dụng while hoặc do - while

while((c = fgetc(fp)) != EOF)  

Hàm fgetc(fp) trả về một char, Trong trường hợp fgetc(fp) == EOF thì kết thúc quá trình đọc file.

2.3. Các hàm fgetc và fgets

Sử dụng các hàm fgetc và fgets phục vụ cho quá trình đọc dữ liệu từ file văn bản.

2.3.1 Hàm fgetc

Hàm fgetc() được sử dụng để đọc một kí tự từ dữ liệu từ file văn bản.

Cú pháp

int getc(FILE *fp);

đọc một ký tự từ tệp văn bản được xác định bởi con trỏ FILE *fp. fp là tham số hình thức có kiểu con trỏ. fp là kết quả thực hiện của hàm fopen();

Vậy lý do tại sao getc được sử dụng để đọc từng kí tự của FILE mà lại có kết quả trả về là int? Lý do đó là khi thực hiện đọc file, ký tự đánh dấu Kết thúc file (EOF) có giá trị int chứ không phải char.

Ví dụ

Sử dụng hàm getc đọc toàn bộ ký tự được ghi trong file.txt tương ứng với ví dụ hình số 2.

Code minh họa


Hình số 3: Sử dụng hàm fgetc để đọc file

Sử dụng while để kiểm tra kết thúc file (EOF) khi thực hiện đọc file. Kết quả thực hiện in ra được 2 xâu chứa chuỗi ký tự.

2.3.2 Hàm fgets

Hàm fgets được sử dụng đọc xâu kí trong file văn bản tự theo dòng.

Cú pháp

char *fgets(char *str, int n, FILE *fp);

Mô tả

str : Con trỏ char thực chất là string, bản chất là mảng chars

n: số lượng character lớn nhất khi thực hiện đọc, ỏ đây chính là kích cỡ của mảng char

fp: con trỏ FILE

Hàm sẽ thực hiện dừng đọc file văn bản khi một trong các điều kiện sau đây là đúng.

+ Đọc được n-1 bytes.

+ Gặp một dòng mới

+ Đọc khi gặp kí tự kết thúc file.

+ Đọc khi lỗi xuất hiện.

Ví dụ

Sử dụng hàm fgets để đọc file “file.txt” ở ví dụ được trình bày tại hình 2.

Code minh họa


Hình số 4: Sử dụng hàm fgets

Khi sử dụng hàm fgets để đọc nội dung của “file.txt”, sử dụng while để thực hiện đọc từng dòng dữ liệu text. Và thực hiện in ra kết quả bằng việc sử dụng hàm printf.

2.3.3 Hàm fscanf

Hàm đọc giá trị từ tệp văn bản. Hàm này gọi là hàm hướng trường dữ liệu (field-oriented function). Đặc trưng của hàm ngày cũng tương tự như hàm scanf. Hàm scanf khi đọc dữ liệu từ bàn phím, nếu gặp ký tự trống thì lập tức nó coi như kí tự phân cách giữa các trường và chấm dứt việc đọc dữ liệu đây là vấn đề có sự khác nhau giữa hàm scanf và hàm gets.

Ví dụ Hàm scanf


Hình số 5 : Hàm scanf

Trong ví dụ trên : Khi nhập “Programming C with file”, thì nội dung thông tin in ra là “Programming” điều đó có nghĩa là hàm scanf khi gặp dấu trống lập tức chấm dứt việc ghi thông tin.

Nếu thay hàm scanf băng hàm gets thì nội dung thông tin sẽ được hiển thị đầy đủ

Code minh họa


Hình số 6 : Hàm gets

Tương tự như fscanf được sử dụng để đọc file, khi gặp dấu trống thì hàm fscanf dẽ coi nó như dấu phân cách giữa các trường. Vì nó là hàm hướng trường dữ liệu do vậy nó sẽ kết thúc quá trình đọc 1 trường thông tin (1 cột) khi gặp dấu phân cách giữa các trường.

Ví dụ:

Lưu ý khi đọc file văn bản, để chắc chắn chúng ta sử dụng hàm rewind() để thiết lập vị trí con trỏ đọc file về đầu file.

char str[100];

FILE * fp;

fp = fopen ("file.txt", "r");

fscanf(fp, "%s", str);

printf("Read String |%s|\n", str );

Khi đó kết quả in ra chỉ là “Ngon”,

Vậy hàm fscanf nếu đọc các file văn bản có format duoi dạng các cột thông tin hay các bảng chứa dữ liệu thì độ hiện quả sẽ rất tốt.

 

 

 

vertical_align_top
share
Chat...