Đọc file trong C (fgetc, fgets, fscanf, sscanf)

Cùng khám phá về cách đọc file trong C. Bạn sẽ học được cách đọc một file trong C bằng 4 hàm có sẵn là fgetc, fgets, fscanf & sscanf. Bạn cũng sẽ học được cách vận dụng các hàm này để đọc số từ file trong ͼ, đọc chuỗi từ file trong ͼ, cũng như là để đọc mảng từ file trong C sau bài học này.

Tất cả chúng ta có 4 phương thức để đọc file trong C như sau:

  • Đọc từng ký tự trong file bằng hàm fgetc
  • Đọc từng dòng file trong C bằng hàm fgets
  • Đọc từng dòng file theo định dạng chỉ định bằng hàm fscanf
  • Đọc từng dòng file theo định dạng chỉ định bằng hàm fgets phối hợp hàm sscanf

Nội dung này sẽ lưu tâm về cách đọc file trong C. Về quy trình tổng quát giải quyết file trong C, hãy tìm hiểu tại bài sau:

  • Tìm hiểu thêm: Giải quyết file trong ͼ

Trước khi đọc file trong C

Để đọc file trong C, bạn cần phải mở nó trước bằng một trong hai hàm đọc file là fopen hoặc fopen_s mà Kiyoshi đã chỉ dẫn trong bài Mở file trong C.

Cảnh báo là tùy thuộc vào vào mục đích của việc đọc file mà mode dùng để mở file cũng sẽ khác nhau, cho nên tất cả chúng ta cần hết sức lưu ý khi lựa chọn mode khi mở file.

Ở giai đoạn này, mode đọc file chính là thông tin về những việc cần làm với một file. Các mode có thể dùng để đọc file trong C như sau:

ModeXử lýChức năngrMở để đọcChỉ cho phép đọc file
Nếu file không tồn tại thì trả về NULLr+Mở để đọc & ghi đèCho phép cả đọc & ghi đè
Nếu file không tồn tại thì trả về NULLw+Mở để đọc & ghi đèCho phép cả đọc & ghi đè
Nếu file không tồn tại thì tạo file mớia+Mở để đọc & ghi chènCho phép cả đọc & ghi chèn
Nếu file không tồn tại thì tạo file mới

Chẳng hạn, nếu bạn chỉ mong muốn mở để đọc file, hãy dùng tới mode r như sau:

FILE * fp =

NULL

;


fp = fopen(

"sample.txt"

,

"r"

);


Ngoài ra nếu bạn mong muốn mở file để vừa đọc & vừa ghi đè bài viết mới vào file đó, hiện giờ mode cần dùng để mở file không phải là mode r, mà sẽ là mode r+ ví dụ.

FILE * fp =

NULL

;


fp = fopen(

"sample.txt"

,

"r+"

);


Cụ thể về các mode đọc file cũng được trình bày đầy đủ trong bài Mở file trong C.

Sau thời điểm đã mở file thành công bình một trong hai hàm trên, hiện giờ tất cả chúng ta đã có thể tiến hành đọc dữ liệu từ file trong ͼ với các phương thức sau đây.

Đọc từng ký tự trong file bằng hàm fgetc

Hàm fgetc trong C là một hàm có sẵn trong thư viện chuẩn, có công dụng đọc từng ký tự trong file chỉ định. Tên hàm fgetc được viết tắt bởi cụm từ file, get & character, được dịch theo tiếng Việt đúng đắn là hàm đọc từng ký tự trong file.

Tất cả chúng ta sử dụng hàm fgetc trong C với cú pháp sau đây:

int fgetc(FILE * fp);

Trong số đó fp là con trỏ của file cần đọc, được tạo nên từ việc mở file ở phần trên.

Hàm fgetc sẽ trả về mã ASCII của 1 ký tự được đọc ra từ file. Trong trường hợp địa điểm đọc ký tự đã là cuối file, hoặc là việc đọc file thất bại thì giá trị EOF sẽ được trả về. Bằng việc in mã ASCII này sang dạng char, tất cả chúng ta có thể lấy xuất được ký tự đã đọc.

Chẳng hạn rõ ràng và cụ thể, tất cả chúng ta có file sample.txt với bài viết sau đây:

Hello
World    

Tất cả chúng ta sẽ dùng hàm fopen để mở file, sau đó đọc 1 ký tự trong file bằng hàm fgetc như sau:



int

main

(

void

)


{


FILE * fp =

NULL

;




fp= fopen(

"sample.txt"

,

"r"

);



printf

(

"%cn"

, fgetc(fp));


printf

(

"%cn"

, fgetc(fp));


}


Kết quả:

Н


e


Bạn có thể thấy tất cả chúng ta chỉ có thể đọc từng ký tự từ file trong mỗi lần chạy hàm fgetc mà thôi.

Để có thể đọc toàn bộ các ký tự từ trong file, tất cả chúng ta sẽ cần tạo nên một vòng lặp để đọc từng ký tự từ đầu file cho tới cuối file, cho tới khi kết quả trả về là giá trị EOF như sau:



int

main

(

void

)


{


FILE * fp =

NULL

;



fp= fopen(

"sample.txt"

,

"r"

);



char

ͼ;



while

((ͼ = fgetc(fp)) != EOF)


{



printf

(

"%c"

, ͼ);


}



fclose(fp);



return

;


}


Kết quả, toàn thể các ký tự được đọc & xuất lần lượt ra màn dường như sau:

Hello


World


Cảnh báo ở giai đoạn này, các ký tự xuống dòng cũng được đọc từ file & vì vậy kết quả xuất ra màn hình cũng được xuống dòng như trên.

Đọc từng dòng file trong C bằng hàm fgets

Hàm fgets trong C

Việc đọc từng ký tự bằng hàm fgetc thật là vất vả phải không nào? Này là nguyên nhân mà hàm fgets với tính năng đọc từng dòng trong file đã được chào đời.

Hàm fgets trong C là một hàm có sẵn trong thư viện chuẩn, có công dụng đọc từng dòng trong file chỉ định. Tên hàm fgets được viết tắt bởi cụm từ file, get & string, được dịch theo tiếng Việt đúng đắn là hàm đọc từng dòng trong file.

Tất cả chúng ta sử dụng hàm fgets trong C với cú pháp sau đây:

char * fgets(char * buf, int size, FILE * fp);

Trong số đó:

  • fp là con trỏ của file cần đọc, được tạo nên từ việc mở file
  • buf là con trỏ tới nơi lưu trữ chuỗi đã đọc từ dòng trong file. Thông thường tất cả chúng ta chỉ định buf bằng một mảng.
  • size là kích cỡ (số ký tự) lớn nhất có thể đọc từ dòng trong file.

Hàm fgets sẽ trả về con trỏ lưu địa chỉ trên bộ nhớ lưu trữ của chuỗi được đọc từ dòng trong file. Trong trường hợp địa điểm đọc ký tự đã là cuối file, hoặc là việc đọc file thất bại thì con trỏ NULL sẽ được trả về.

Xem Thêm  DELETE (Transact-SQL) - Máy chủ SQL - máy chủ sql xóa khỏi

Lại nữa, hàm fgets sẽ đọc một dòng từ file, & dòng đó được tính từ đầu dòng cho tới khi gặp ký tự xuống dòng ռ.

Chẳng hạn dùng hàm fgets để đọc từng dòng file trong C

Chẳng hạn rõ ràng và cụ thể, tất cả chúng ta có file nums.txt với bài viết sau đây:

1234567
89abc
def

Tất cả chúng ta sẽ dùng hàm fopen để mở file, sau đó đọc từng dòng trong file bằng hàm fgets như sau:



int

main

(

void

)


{


FILE * fp =

NULL

;


char

arr[

128

];




fp= fopen(

"nums.txt"

,

"r"

);




fgets(arr,

128

, fp);


printf

(

"%s"

, arr);




fgets(arr,

128

, fp);


printf

(

"%s"

, arr);



}


Kết quả:

1234567


89abc


Bạn có thể thấy tất cả chúng ta chỉ có thể đọc từng dòng từ file trong mỗi lần chạy hàm fgetc mà thôi.

Để có thể đọc toàn bộ các dòng từ trong file, tất cả chúng ta sẽ cần tạo nên một vòng lặp để đọc từng dòng từ đầu file cho tới cuối file, cho tới khi kết quả trả về là giá trị NULL như sau:



int

main

(

void

)


{


FILE * fp =

NULL

;


char

arr[

128

];




fp= fopen(

"nums.txt"

,

"r"

);




while

(fgets(arr,

128

, fp) !=

NULL

)


{



printf

(

"%s"

, arr);


}



fclose(fp);



return

;


}


Kết quả, toàn thể các dòng được đọc & xuất lần lượt ra màn dường như sau:

1234567


89abc


def


Đọc từng dòng file khi đối số size bé hơn số ký tự

Đối số size trong hàm fgets giúp tất cả chúng ta chỉ định số ký tự lớn nhất có thể được đọc từ một dòng trong file. Thông thường tất cả chúng ta chỉ định giá trị của size bằng với số phần tử của mảng chuẩn bị để lưu bài viết đọc từ dòng đó.

Cảnh báo trong trường hợp giá trị của size bé hơn số ký tự thực có trong dòng, thì chỉ có size -1 ký tự thực được đọc ra từ dòng này mà thôi. Chỗ trống của ký tự sót lại sẽ được auto lấp chỗ bằng một ký tự chấm dứt chuỗi .

Chẳng hạn, tất cả chúng ta sẽ đọc lại file nums.txt ở trên, nhưng với chỉ định số phần tử lớn nhất có thể đọc lại bé hơn số ký tự thực trong dòng như sau:



int

main

(

void

)


{


FILE * fp =

NULL

;


char

arr[

128

];




fp= fopen(

"nums.txt"

,

"r"

);




fgets(arr,

3

, fp);


printf

(

"%sn"

, arr);




fgets(arr,

4

, fp);


printf

(

"%s"

, arr);



}


Kết quả:

12


345


Tại sao lại chỉ đọc được 2 ký tự ở lần một từ dòng, & vì sao ở lần hai lại khởi đầu đọc dòng từ ký tự 3 chứ?

Câu giải đáp là ở lần đọc 1 tất cả chúng ta chỉ định đọc 3 ký tự từ dòng, bên cạnh đó chỉ có 2 ký tự thực là 12 được đọc, chỗ trống sót lại được dành để điền ký tự chấm dứt chuỗi rồi.

& ở lần đọc thứ 2, hàm fgets cũng sẽ khởi đầu đọc từ cùng một dòng ban đầu do dòng này chưa được đọc hết ký tự. & địa điểm khởi đầu được đọc chính là từ ký tự chấm dứt chuỗi mới được điền ở lần đọc trước hết.

Đọc từng dòng file theo định dạng chỉ định bằng hàm fscanf

Sự lợi hại của hàm fscanf trong C

Ở phần trên tất cả chúng ta đã biết phương pháp đọc từng dòng trong file bằng hàm fgets rồi.

Ngoài ra còn tồn tại một hàm lợi hại hơn nữa giúp tất cả chúng ta đọc từng dòng trong file với bài viết chắt lọc, chẳng hạn như khi tất cả chúng ta chỉ mong muốn đọc chuỗi từ file trong ͼ, hoặc là khi chỉ mong muốn đọc số từ file trong ͼ.

Đó chính là hàm fscanf giúp tất cả chúng ta đọc từng dòng file theo định dạng chỉ định trong C.

Hàm này đặc biệt hữu ích khi cần đọc các file được viết theo định dạng cố định. Chẳng hạn như khi tất cả chúng ta cần đọc file csv trong ͼ với các ô trong file được phân cách bởi dấu phẩy, hoặc là bằng dấu cách ví dụ.

Hàm fscanf trong C là gì

Hàm fscanf trong C là một hàm có sẵn trong thư viện chuẩn, có công dụng đọc từng dòng file theo định dạng chỉ định. Hàm fscanf không đọc toàn thể bài viết của dòng, mà sẽ phân chia bài viết dòng đó theo từng định dạng chỉ định, qua đó có thể truy xuất các thông tin thiết yếu mà người dùng mong muốn lấy ra từ dòng đó, chẳng hạn như là chỉ lấy các số trong dòng, hoặc là chỉ lấy các chuỗi trong dòng được viết theo một quy luật (định dạng) rõ ràng và cụ thể.

Các dữ liệu được truy xuất từ dòng theo định dạng chỉ định cũng sẽ được lưu trữ với định dạng tương ứng trong chương trình, giúp tất cả chúng ta đọc các dữ liệu từ file một cách có chắt lọc & chuyên sâu năng suất sử dụng chương trình.

Chẳng hạn rõ ràng và cụ thể, tất cả chúng ta có thể chỉ đọc số từ file trong ͼ hoặc là chỉ đọc chuỗi từ file trong ͼ & bỏ qua các loại dữ liêu khác trong dòng.

Tất cả chúng ta sử dụng hàm fscanf trong C với cú pháp sau đây:

int fscanf(FILE * fp, “fo1 fo2 fo3 … “, add1, add2, add3 …);

Trong số đó

  • fp là con trỏ của file cần đọc, được tạo nên từ việc mở file ở phần trên.
  • Các cặp fo & add tương ứng là định dạng (format) của dữ liệu cần đọc từ dòng, & địa chỉ của tên biến (con trỏ biến) dùng để lưu dữ liệu đó trong bộ nhớ lưu trữ.

Hàm fscanf sẽ trả về một số thuộc kiểu int, chính là số mục có thể đọc được từ dòng. Trong trường hợp dòng được đọc đã là dòng cuối file, hoặc là việc đọc file thất bại thì giá trị EOF sẽ được trả về.

Cảnh báo là giống với hàm fgets thì hàm fscanf cũng chỉ có thể đọc lần lượt từng dòng trong file, vì vậy tất cả chúng ta cần phải sử dụng tới một vòng lặp để có thể đọc toàn thể các dòng trong file.

Xem Thêm  Thủ tục được lưu trữ trong máy chủ sql là gì - thủ tục được lưu trữ trong sql là gì

Lại nữa, định dạng (format) của dữ liệu cần đọc cũng như kiểu của biến lưu dữ liệu được tóm lược trong bảng dưới đây:

Định dạng chuyển đổiKiểu biếnChi tiếtphần trămhhdchar
unsigned charChuyển về dạng thập phân & lưu trữ trong biến 1 bytephần trămhdshort
unsigned shortChuyển về dạng thập phân & lưu trữ trong biến 2 bytephần trămdint
unsigned intChuyển về dạng thập phân & lưu trữ trong biến kiểu intphần trămldlong
unsigned longChuyển về dạng thập phân & lưu trữ trong biến 4 bytephần trămhhxchar
unsigned charChuyển về hệ thập lục phân & lưu trữ trong biến 1 bytephần trămhxshort
unsigned shortChuyển về hệ thập lục phân & lưu trữ trong biến 2 bytephần trămxint
unsigned intChuyển về hệ thập lục phân & lưu trữ trong biến kiểu intphần trămlxlong
unsigned longChuyển về hệ thập lục phân & lưu trữ trong biến 4 bytephần trămffloatChuyển về số thực dấu phẩy động & lưu trữ trong biến kiểu floatphần trămlfdoubleChuyển về số thực dấu phẩy động & lưu trữ trong biến kiểu doublephần trămccharChuyển về 1 ký tự & lưu trữ trong biến kiểu charphần trămschar *Chuyển về chuỗi ký tự & lưu trữ trong biến kiểu mảng charphần trămpvoid *Chuyển về địa chỉ & lưu trữ trong con trỏ

Sau đây tất cả chúng ta sẽ cùng khám phá các cách dùng hàm fscanf để mở file với định dạng chỉ định như sau:

Đọc số từ file trong ͼ

Bằng cách chỉ định định dạng dữ liệu cần đọc dưới dạng số trong hàm fscanf, tất cả chúng ta có thể tiến hành đọc số từ file trong ͼ.

Chẳng hạn, tất cả chúng ta có file user.txt với bài viết sau đây:

Kiyoshi 32 172.5cm ?
Honda 24 185.3cm Σ
Suzuki 63 153.8cm Ɓ

Giả sử tất cả chúng ta chỉ mong muốn đọc dữ liệu số bao gồm cột tuổi & chiều cao trong từng dòng file trên, khi đó tất cả chúng ta dùng hàm fscanf như sau:



int

main

(

void

)

{


FILE * fp =

NULL

;


char

name[

32

] = {

};


int

age =

;


double

height =

;


char

blood =

;




fopen_s(&fp,

"user.txt"

,

"r"

);




while

(

fscanf

(fp,

"%s %d %lfcm %c"

, name, &age, &height, &blood) != EOF)


{



printf

(

"%d %3.2lf n"

, age, height);


}


return

;


}


Kết quả:

32 172.50


24 185.30


63 153.80


Cảnh báo là khi đọc từng dòng trong file bằng hàm fscanf thì tất cả chúng ta cần đọc toàn bộ các mục có thể đọc ra, bên cạnh đó khi cần xuất dữ liệu số thì tất cả chúng ta chỉ cần chỉ định các dữ liệu này mà thôi.

Đọc chuỗi từ file trong ͼ

Cũng giống như trên thì bằng cách chỉ định định dạng dữ liệu cần đọc dưới dạng số trong hàm fscanf, tất cả chúng ta có thể tiến hành đọc chuỗi từ file trong ͼ.

Chẳng hạn, tất cả chúng ta cũng đọc file user.txt với bài viết sau đây:

Kiyoshi 32 172.5cm ?
Honda 24 185.3cm Σ
Suzuki 63 153.8cm Ɓ

Giả sử tất cả chúng ta chỉ mong muốn đọc dữ liệu chuỗi bao gồm cột tên & nhóm máu trong từng dòng file trên, khi đó tất cả chúng ta dùng hàm fscanf như sau:



int

main

(

void

)

{


FILE * fp =

NULL

;


char

name[

32

] = {

};


int

age =

;


double

height =

;


char

blood =

;




fopen_s(&fp,

"user.txt"

,

"r"

);




while

(

fscanf

(fp,

"%s %d %lfcm %c"

, name, &age, &height, &blood) != EOF)


{



printf

(

"%s %cn"

, name, blood);


}


return

;


}


Kết quả:

Kiyoshi ?


Honda Σ


Suzuki Ɓ


Cảnh báo là khi đọc từng dòng trong file bằng hàm fscanf thì tất cả chúng ta cần đọc toàn bộ các mục có thể đọc ra, bên cạnh đó khi cần xuất dữ liệu chuỗi thì tất cả chúng ta chỉ cần chỉ định các dữ liệu này mà thôi.

Đọc từng dòng file theo định dạng chỉ định bằng hàm sscanf

Hàm sscanf trong C là một hàm có sẵn trong thư viện chuẩn, có công dụng truy xuất thông tin theo định dạng chỉ định từ một chuỗi ký tự. Bằng cách vận dụng hàm sscanf, tất cả chúng ta có thể lấy ra các thông tin thiết yếu từ chuỗi theo một định dạng chỉ định nào đó.

Cú pháp sử dụng hàm sscanf trong C như sau:

int sscanf (buff, “fo1 fo2 fo3 … “, add1, add2, add3 …);

Trong số đó

  • buff là con trỏ tới chuỗi ký tự cần nghiên cứu để lấy ra thông tin theo định dạng
  • Các cặp fo & add tương ứng là định dạng (format) của dữ liệu cần đọc từ chuỗi ký tự, & địa chỉ của tên biến dùng để lưu thông tin được tách ra từ chuỗi trên bộ nhớ lưu trữ.

& định dạng (format) sử dụng trong hàm sscanf thì cũng giống như với hàm fscanf mà Kiyoshi đã giới thiệu ở trên.

Vận dụng hàm sscanf, tất cả chúng ta có thể đọc từng dòng trong file & lấy ra các thông tin theo một chỉ định rõ ràng và cụ thể, bằng cách chỉ định chuỗi ký tự cần nghiên cứu trong hàm sscanf chính là bài viết từng dòng trong file được đọc bằng hàm gets.

Nói một cách dễ hiểu thì cách dùng của nó rất giống với hàm fscanf ở trên, loại trừ việc nó sẽ giải quyết bài viết dòng được đọc bởi hàm fgets mà thôi.

Chẳng hạn rõ ràng và cụ thể, tất cả chúng ta có file check.txt với bài viết sau đây:

test01 1.0 1.1 1.2 1.3 1.4
test02 2.0 2.1 2.2 2.3 2.4
test03 3.0 3.1 3.2 3.3 3.4

Bằng việc sử dụng hàm fgets để đọc từng dòng trong file này, sau đó dùng hàm sscanf để lấy thông tin thiết yếu theo định dạng từ dòng, mà tất cả chúng ta có thể đọc từng dòng trong file với định dạng chỉ định như sau:





int

main

(

void

)

{


FILE *fp;


char

fname[] =

"test.txt"

;


char

line[N];


char

str[

16

];


float

f1, f2, f3, f4, f5;




fp = fopen(fname,

"r"

);


if

(fp ==

NULL

) {


printf

(

"%s file not open!n"

, fname);


return

-1

;


}




while

(fgets(line, И, fp) !=

NULL

) {



sscanf

(line,

"%s %f %f %f %f %f"

, str, &f1, &f2, &f3, &f4, &f5);


printf

(

"%s %.1f %.1f %.1f %.1f %.1fn"

, str, f1, f2, f3, f4, f5);


}



fclose(fp);



return

;


}


Kết quả:

test01 1.0 1.1 1.2 1.3 1.4


test02 2.0 2.1 2.2 2.3 2.4


test03 3.0 3.1 3.2 3.3 3.4


Đọc file csv trong C

File csv thường có định dạng cố định, trong đó giữa các dữ liệu trong một hàng có thể được phân cách bởi một dấu phẩy, hoặc là bằng dấu cách.

Xem Thêm  Cảnh báo JavaScript ⚠💀 Hộp & Biểu ngữ cảnh báo tùy chỉnh 🚩 [Hướng dẫn] - hộp cảnh báo tùy chỉnh javascript

& để đọc các file có định dạng cố định như vậy này thì tất cả chúng ta có thể dùng hàm fscanf, hoặc là tổ hợp hàm fgets & hàm sscanf mà Kiyoshi đã giới thiệu ở trên.

Sau đây, hãy cùng khám phá cách sử dụng hàm fscanf để đọc file csv trong C nhé.

Mở file CSV có các cột phân chia bởi dấu cách

Giả sử tất cả chúng ta có file check.csv với bài viết sau đây:

test01 1.0 1.1 1.2 1.3 1.4
test02 2.0 2.1 2.2 2.3 2.4
test03 3.0 3.1 3.2 3.3 3.4

Tất cả chúng ta sẽ mở file này & đọc từng dòng trong file theo định dạng như sau:



int

main

(

void

)

{


FILE *fp;


char

fname[] =

"test.csv"

;


char

str[

16

];


float

f1, f2, f3, f4, f5;



fp = fopen(fname,

"r"

);



if

(fp ==

NULL

) {


printf

(

"%s file not open!n"

, fname);


return

-1

;


}




while

(

fscanf

(fp,

"%s %f %f %f %f %f"

, str, &f1, &f2, &f3, &f4, &f5) != EOF) {


printf

(

"%s %.1f %.1f %.1f %.1f %.1fn"

, str, f1, f2, f3, f4, f5);


}



fclose(fp);



return

;


}


& kết quả:

test01 1.0 1.1 1.2 1.3 1.4


test02 2.0 2.1 2.2 2.3 2.4


test03 3.0 3.1 3.2 3.3 3.4


Có thể thấy bằng cách thêm dấu cách bên trong định dạng dữ liệu mở file mà tất cả chúng ta đã có thể đọc các dữ liệu cách nhau bởi dấu cách như thể từ từng dòng trong file CSV.

Mờ file CSV có các cột phân chia bởi dấu phẩy

Giả sử tất cả chúng ta có file check.csv với bài viết sau đây:

test01,1.0,1.1,1.2,1.3,1.4
test02,2.0,2.1,2.2,2.3,2.4
test03,3.0,3.1,3.2,3.3,3.4

Một cách tương đương thì tất cả chúng ta cũng mở file này & đọc từng dòng trong file theo định dạng như sau:



int

main

(

void

)

{


FILE *fp;


char

fname[] =

"test.csv"

;


char

str[

16

];


float

f1, f2, f3, f4, f5;



fp = fopen(fname,

"r"

);



if

(fp ==

NULL

) {


printf

(

"%s file not open!n"

, fname);


return

-1

;


}




while

(

fscanf

(fp,

"%[^,],%f,%f,%f,%f,%f"

, str, &f1, &f2, &f3, &f4, &f5) != EOF) {


printf

(

"%s,%.1f,%.1f,%.1f,%.1f,%.1f"

, str, f1, f2, f3, f4, f5);


}



fclose(fp);



return

;


}


& kết quả:

test01,1.0,1.1,1.2,1.3,1.4


test02,2.0,2.1,2.2,2.3,2.4


test03,3.0,3.1,3.2,3.3,3.4


Có thể thấy bằng cách thêm dấu phẩy bên trong định dạng dữ liệu mở file mà tất cả chúng ta đã có thể đọc các dữ liệu cách nhau bởi dấu phẩy như thể từ từng dòng trong file.

Đọc mảng từ file trong C

So với các file có định dạng cố định như là CSV, thì khi tất cả chúng ta cũng có thể đọc mảng từ file trong C.

Chẳng hạn, tất cả chúng ta có file check.csv có bài viết sau đây:

test01,1.0,1.1,1.2,1.3,1.4
test02,2.0,2.1,2.2,2.3,2.4
test03,3.0,3.1,3.2,3.3,3.4

Có thể thấy với file CSV này thì các ô trong hàng được cách nhau bởi dấu phẩy, trong đó ô trước hết ở dạng chuỗi ký tự, & các ô sau thì ở dạng số thực.

Do các dòng trong file đều có chung kết cấu như thế, nên sau thời điểm đọc từng dòng của file bằng hàm fscanf, hoặc là tổ hợp hàm fgets & hàm sscanf mà Kiyoshi đã giới thiệu ở trên, tất cả chúng ta có thể lưu chuỗi ký tự đọc được từ ô trước hết vào một mảng chuỗi, & các số đọc được từ các ô sót lại thì lưu vào trong mảng số khi đọc từng dòng trong file. Đây là cách đọc mảng từ file trong C.

& với từng dòng như thế, do tồn tại 2 mảng với 2 kiểu dữ liệu khác nhau, nên tất cả chúng ta sẽ nhóm hai loại dữ liệu khác nhau này trong một tập hợp cho dễ làm chủ thông qua kiểu kết cấu trong C.

Đây cũng chính là cách Đọc kết cấu từ file trong C. Nói một cách dễ hiểu thì tất cả chúng ta sẽ chỉnh lý các dữ liệu đọc được từ file & lưu chúng vào các mảng & kiểu dữ liệu để đơn giản giải quyết chúng trong chương trình.

Dĩ nhiên sau thời điểm đã lưu chúng vào mảng hoặc kết cấu rồi, tất cả chúng ta tuyệt đối có thể sử dụng các phương thức giải quyết mảng hoặc phương thức giải quyết kết cấu để giải quyết dữ liệu đọc được từ chuỗi. Bạn cũng có thể xem qua các phương thức này tại hai chuyên mục là Mảng trong C & Kiểu kết cấu trong C.

& tất cả chúng ta sẽ đọc mảng từ file với chương trình như sau:







typedef

struct

str

{


char

str[

16

];


float

f_data[

5

];


} data;



int

main

(

void

)

{


FILE *fp;


char

fname[] =

"test.csv"

;


char

line[N];


char

str[

16

];


float

f1, f2, f3, f4, f5;


int

ι =

;




data data[ROW];



fp = fopen(fname,

"r"

);


if

(fp ==

NULL

) {


printf

(

"%s file not open!n"

, fname);


return

-1

;


}



while

(fgets(line, И, fp) !=

NULL

) {



sscanf

(line,

"%[^,],%f,%f,%f,%f,%f"

, str, &f1, &f2, &f3, &f4, &f5);





for

(

int

j =

; j <

sizeof

(data[i].str) /

sizeof

(data[i].str[

]); j++) {


data[i].str[j] = str[j];


}


float

tmp[] = {f1, f2, f3, f4, f5};


for

(

int

j =

; j <

sizeof

(data[i].f_data) /

sizeof

(data[i].f_data[

]); j++) {


data[i].f_data[j] = tmp[j];


}




printf

(

"%s,%.1f,%.1f,%.1f,%.1f,%.1fn"

, data[i].str, data[i].f_data[

], data[i].f_data[

1

], data[i].f_data[

2

], data[i].f_data[

3

], data[i].f_data[

4

]);


ι++;


}



fclose(fp);



return

;


}


& kết quả đọc mảng từ file trong C như sau:

test01,1.0,1.1,1.2,1.3,1.4


test02,2.0,2.1,2.2,2.3,2.4


test03,3.0,3.1,3.2,3.3,3.4


Cảnh báo trong định dạng dữ liệu sử dụng trong hàm sscanf, tất cả chúng ta đã dùng tới biểu thức chính quy với cách viết %[^,], có công dụng lấy các dữ liệu chuỗi loại trừ dấu phẩy. Nguyên nhân là dấu phẩy được thừa nhận là một phần của chuỗi, vì vậy, tất cả chúng ta cần dùng biểu thức chính quy để loại bỏ dấu phẩy này từ trong kết quả đọc chuỗi.

Kết luận

Trên đây Kiyoshi đã chỉ dẫn các bạn về cách đọc file trong C rồi. Để nắm vững bài viết bài học hơn, bạn hãy thực hành viết lại các chẳng hạn của ngày lúc này nhé.

& hãy cùng khám phá những tri thức sâu hơn về C trong các bài học kế tiếp.

Viết một bình luận