TẠO FILE TRONG C++

     

Chào các bạn đang theo dõi khóa học lập trình trực tuyến ngữ điệu C++.

Bạn đang xem: Tạo file trong c++

Trong bài học kinh nghiệm này, chúng ta sẽ cùng khám phá về các khái niệm về file và cách để thao tác với file trong ngữ điệu lập trình C/C++.

File

Nếu máy tính xách tay của chúng ta có ổ cứng, hoặc các bạn có USB hoặc bất kỳ thiết bị lưu trữ nào thì chắn chắn chắn chúng ta đã từng thao tác làm việc với File. Khi chúng ta chơi một trò chơi offline, tin tức nhân vật, điểm số, ... Sẽ tiến hành lưu trữ vào File để khi chương trình game bị tắt đi thì các bạn không đề nghị chơi lại từ đầu. Khi các bạn cài đặt cấu hình cho một trong những phần mềm và tắt đi, cấu hình đó được lưu giữ vào File để lần làm việc tiếp theo vẫn sử dụng. Giỏi khi chúng ta biên dịch một lịch trình C++ bên trên Visual Studio 2015, C++ Compiler của Visual studio đã đọc mã nguồn các bạn đã viết trong số file *.trangantravel.vn để kiểm tra lỗi và dịch chúng sang tệp tin *.obj. Ngay cả hệ điều hành và quản lý Windows mà các bạn đang thực hiện cũng là tập hợp của đa số file được lưu trữ bên phía trong phân vùng ổ đĩa cần sử dụng cho Hệ điều hành...

Đó là một trong những vài ví dụ cho thấy sự sống thọ của tệp tin trong sản phẩm tính. Vậy thì chúng ta đã thao tác làm việc với đầy đủ File đó như thế nào?

Làm việc với File bọn họ chỉ có các thao tác cơ bản như: tạo ra file mới, đọc tài liệu trong file, ghi tài liệu vào file, xóa file... Và bọn họ làm điều đó hằng ngày, khi bọn họ chơi game, khi chứng kiến tận mắt phim trên sản phẩm tính, ... Và trong cả khi chúng ta lập trình, mã mối cung cấp của bọn họ được giữ xuống tệp tin mã nguồn lúc nhấn tổ hợp phím Ctrl + S.

Theo có mang trên Wikipedia về computer file: Một tệp tin trên máy tính xách tay là một tài nguyên dùng để làm lưu trữ thông tin lâu dài, sử dụng cho những chương trình thứ tính.

Cũng giống như việc lưu trữ dữ liệu tạm thời trên RAM, file cũng tàng trữ dữ liệu bên dưới dạng nhị phân (0 hoặc 1), tuy nhiên tùy vào format của file cùng cách chuyển đổi của mỗi ứng dụng đọc file mà bọn họ có đa số kiểu thông tin khác nhau. Ví dụ tệp tin .png thì được đưa về hình dạng ảnh, ứng dụng Microsoft Word gửi dãy bit nhị phân về dạng text...

Trong ngôn từ lập trình C/C++: file là hình trạng đối tượng, nó khẳng định một stream và chứa các thông tin quan trọng để điều khiển, gồm một con trỏ trỏ mang lại buffer của nó, các chỉ mục và trạng thái của nó.

Các chúng ta có thể hiểu file (trong ngữ điệu lập trình C/C++) là một trong kiểu đối tượng mà thông qua nó chúng ta cũng có thể thao tác với dữ liệu được lưu giữ trữ bên phía trong File (chứ không phải là một File trên lắp thêm tính).

Để chúng ta không bị nhầm lẫn, mình đang nói về kiểu dữ liệu FILE được có mang trong tủ sách cstdio (hay stdio.h) mà tất cả thể các bạn đã từng học trong ngữ điệu C. Chúng ta sẽ học biện pháp sử dụng những Stream để làm việc với file gắng vì sử dụng kiểu dữ liệu FILE trong số bài học tập sau, dẫu vậy mình nghĩ kiểu dữ liệu FILE trong thư viện cstdio cũng có những ưu thế riêng của nó buộc phải mình không bỏ qua bài học này.

Làm bài toán với tệp tin type trong C/C++

Trong bài học này, mình vẫn hướng dẫn chúng ta thực hiện tại các làm việc như mở file, đọc cùng ghi dữ liệu trong file... Bọn họ cần làm việc trên một file ví dụ nào đó phải mình sẽ khởi tạo một tệp tin với tên file là my_document.txt trong folder Desktop có đường dẫn trên đồ vật mình là: C:/Users/ADMIN/Desktop/my_document.txt

Để thao tác với file, bọn họ cần biết vị trí của tệp tin (thông qua đường dẫn) để bé trỏ vẻ bên ngoài FILE hoàn toàn có thể tạo được luồng dữ liệu giữa người dùng và file trên trang bị lưu trữ.

#include #include int main()const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;return 0;Open fileĐể mở một file, các chúng ta có thể sử dụng hàm fopen được tư tưởng trong tủ sách cstdio:

FILE* fopen(const char *file, const char *mode);Hàm fopen chất nhận được tạo một kết nối đến file với đường truyền được lưu trữ bởi tham số sản phẩm nhất. Nếu file không tồn tại, file new sẽ được tạo nên với tên file như trong mặt đường dẫn. Tham số thứ hai xác định kiểu truy vấn vào file. Bảng dưới đây liệt kê các mode dùng làm mở một file trong C:


*

Nếu mở file thành công, một showroom của một đối tượng kiểu FILE sẽ được trả về. Trường hợp mở file đại bại thì trả về NULL.

const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "r");if (!file)std::cout << "Can not mở cửa this file" << std::endl;elsestd::cout << "File is opened" << std::endl;Trong đoạn công tác trên, bản thân mở tệp tin đã chế tạo ra sẵn trong folder Desktop cùng với mode "r" (chỉ dùng làm đọc dữ liệu).

Các các bạn cần lưu ý rằng tệp tin trong laptop tồn tại ở 2 dạng: tệp tin văn phiên bản và file bị mã hóa.

File văn phiên bản là phần đa file cơ mà các bạn có thể đọc được lúc mở bằng những trình biên soạn thảo văn bản, thường thì những tệp tin này được định hình Unicode (hoặc phần đa định dạng sử dụng cho văn phiên bản khác).

File bị mã hóa (thường call là tệp tin nhị phân) cần thiết đọc được lúc mở tệp tin bằng những trình biên soạn thảo văn bản. Thực hiện File bị mã hóa giúp chúng ta bảo mật dữ liệu tốt hơn tệp tin văn bản.

Các mode mà tôi đã liệt kê sinh sống bảng trên chỉ dùng để thao tác với tệp tin văn bản. Khi thao tác với tệp tin bị mã hóa (file nhị phân), chúng ta cần nối thêm kí trường đoản cú b (binary) vào ngay sau mode mà các bạn chọn. Ví dụ: "rb", "wb", "ab", "rb+", "r+b", ...

Close file

Sau khi làm việc với file xong, các bạn cần đóng file lại để tránh hồ hết lỗi phạt sinh ko kể ý muốn. Để đóng góp file, họ sử dụng hàm fclose:

int fclose(FILE *file);Trong đó, file là nhỏ trỏ được dùng để lưu trữ add của đối tượng người dùng FILE đang mở. Nếu đóng file thành công xuất sắc thì trả về giá trị 0, ngược lại trả về EOF (End of file).

const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "r");if (!file)std::cout << "Can not open this file" << std::endl;elsestd::cout << "File is opened" << std::endl;fclose(file);Hàm fclose vẫn giải phóng tất cả dữ liệu không được xử lý trên tệp tin nếu chúng vẫn còn đó lưu vào buffer, đóng file lại, cùng giải phóng toàn vùng nhớ mà đối tượng người tiêu dùng FILE sử dụng.

Write data to lớn file

Các chúng ta đã triển khai được thao tác mở và đóng file, nhưng lại lúc này, tệp tin mới tạo ra vẫn chưa xuất hiện dữ liệu đề nghị mình sẽ thực hiện thao tác làm việc ghi dữ liệu vào tệp tin trước. Để mở file cho chính sách ghi file, bọn họ có những mode "w", "r+", "w+", "a", "a+". Tôi chỉ muốn ghi dữ liệu nên mình sẽ lựa chọn mode "w".

Nhưng trước hết, bọn họ nên tách thao tác ghi file ra một hàm riêng có dạng:

void writeToFile(FILE *file);Hàm này sẽ được gọi sau khi mở file và trước khi đóng file.

const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "w");if (!file)std::cout << "Can not xuất hiện this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);fclose(file);Bây giờ, họ chỉ suy nghĩ nội dung bên trong hàm writeToFile.

Để ghi dữ liệu vào file, họ có các hàm đang được quan niệm sẵn trong tủ sách cstdio như sau:

fputc:

int fputc(int c, tệp tin *f);Hàm fputc đang ghi ký tự bao gồm mã ASCII là c vào tệp tin được trỏ cho bởi con trỏ f. Quý hiếm trả về là EOF trường hợp ghi dữ liệu thất bại, trả về mã ASCII của kí tự được ghi vào nếu tiến hành thành công.

Ví dụ:

void writeToFile(FILE *file)int c = fputc("A", file);std::cout << c << std::endl;Sau khi chạy lịch trình xong, chúng ta mở tệp tin my_document.txt trên Desktop lên đã thấy kí từ bỏ "A" đã được ghi vào, mặt khác trên console cũng in ra mã ASCII của kí từ "A".

fputs:

int fputs(const char *str, tệp tin *f);Hàm fputs ghi một C-Style string vào file được trỏ mang lại bởi con trỏ f cho đến khi gặp kí từ bỏ "".

Ví dụ:

void writeToFile(FILE *file)int c = fputs("hello", file);Sau khi chạy chương trình, các bạn mở file my_document.txt nghỉ ngơi thư mục Desktop vẫn thấy kí từ bỏ "A" thời điểm nãy không thể nữa, thay vào sẽ là chuỗi kí từ "hello".

Xem thêm: Cách Tính Độ Chia Nhỏ Nhất Của Ampe Kế ? Cách Tính Độ Chia Nhỏ Nhất Ampe Kế

Read data from file

Đầu tiên mình sẽ khởi tạo một hàm khác mang tên là readFromFile như sau:

void readFromFile(FILE *file)//read dataĐể làm các ví dụ trong phần này, bản thân sẽ call hàm này sau khoản thời gian đã hotline hàm writeToFile.

const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "w+");if (!file)std::cout << "Can not xuất hiện this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);readFromFile(file);fclose(file);Lúc này, tệp tin của họ được mở nhằm vừa đọc cùng ghi file, cần mình sẽ áp dụng mode "w+" (hoặc "r+").

Và dưới đây là một số hàm được định nghĩa sẵn trong tủ sách cstdio hỗ trợ bọn họ đọc tài liệu văn phiên bản từ file.

fgetc:

int fgetc(FILE *f);Hàm fgetc hiểu ra một kí tự vào file, internal tệp tin position indicator đang chuyển mang lại kí tự tiếp theo. Quý giá trả về là mã ASCII của kí tự đã đọc được.

Ví dụ:

void readFromFile(FILE *file)std::cout << (char)fgetc(file) << std::endl;fgets:

char* fgets(char *buf, int n, file *f);Hàm fgets hiểu từ tệp tin ra (n - 1) kí tự, vấn đề đọc dữ liệu sẽ ảnh hưởng dừng nếu phát âm được kí tự new line " " hoặc EOF. Chuỗi kí tự đọc được vẫn lưu vào vùng ghi nhớ được cai quản bởi nhỏ trỏ buf, nếu hiểu dữ liệu thành công thì trả về địa chỉ cửa hàng của buf, trái lại trả về NULL.

Ví dụ:

void readFromFile(FILE *file)char str<255>;std::cout << fgets(str, 255, file) << std::endl;std::cout << str << std::endl;Kết quả phát âm file được lưu vào mảng kí từ str.

Reposition stream position indicator

Ghép những ví dụ sống trên lại, họ có một chương trình dễ dàng và đơn giản minh họa cho việc ghi file cùng đọc từng dòng tài liệu (line by line) đã được ghi vào tệp tin như sau:

#include #include #include void writeToFile(FILE *file)for (int i = 1; i <= 5; i++)fprintf(file, "This is an example line %d ", i);void readFromFile(FILE *file)char str<255>;while (fgets(str, 255, file) != NULL)std::cout << str;int main()const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "w+");if (!file)std::cout << "Can not open this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);readFromFile(file);fclose(file);return 0;Tuy nhiên, công dụng cho ra màn hình không như mong muốn.

Nguyên nhân là khi họ gọi hàm writeToFile với truyền vào đó bé trỏ file, bài toán ghi tệp tin đã khiến internal tệp tin position indicator trỏ mang lại vị trí sau cuối trong file. Sau khoản thời gian quay quay trở lại hàm main, họ tiếp tục call hàm readFromFile với cùng 1 con trỏ file. Như vậy, lúc bọn họ đọc tệp tin thì bọn họ lại ban đầu đọc tại vị trí dứt file.

Để hạn chế điều này, chúng ta cần đóng con trỏ tệp tin lại và mở sinh sản một links mới bằng hàm fopen với mode dùng để đọc file. Mặc dù nhiên, làm vì vậy thì code cách xử trí của họ sẽ lâu năm hơn. Thư viện cstdio đã cung cấp cho chúng ta hàm fseek để đổi khác vị trí trỏ đến trong tệp tin của internal file position indicator.

int fseek(FILE *f, long int offset, int origin);Trong đó:

f là bé trỏ trỏ đến đối tượng người sử dụng FILE đã mở.

offset là số bytes được thêm vào đó tính từ địa chỉ origin.

origin là vị trí đặt con trỏ trong file:

*

Như vậy, sau khoản thời gian gọi hàm writeToFile xong, bọn họ cần dịch chuyển internal tệp tin position indicator về đầu file bằng cách như sau:

writeToFile(file);fseek(file, 0, SEEK_SET);readFromFile(file);Sau kia chạy lịch trình thì thấy dữ liệu in ra màn hình đúng giống như những gì chúng ta đã ghi vào file.

Determine kích thước of nội dung of file

Đôi khi họ cần đọc cục bộ nội dung của file vào một trong những vùng nhớ trên Heap, họ sẽ nên biết trước size nội dung tất cả trong tệp tin để cấp phép đủ vùng nhớ trước khi đọc file. Thư viện cstdio chỉ cung ứng cho bọn họ hàm ftell:

long int ftell(FILE *f);Hàm này vẫn trả về địa chỉ của file indicator đang trỏ đến trong file (số bytes của câu chữ file cơ mà indicator đã chu đáo qua).

Như vậy, các chúng ta có thể đọc form size của ngôn từ trong file bằng phương pháp dịch internal tệp tin position indicator về vị trí sau cuối trong file rồi hotline hàm ftell:

__int64 size_of_file(FILE *file)fseek(file, 0, SEEK_END);__int64 size = ftell(file);fseek(file, 0, SEEK_SET);return size;Binary I/O functionsDưới đấy là 2 hàm dùng làm đọc và ghi tài liệu chỉ cần sử dụng cho mode nhị phân.

size_t fwrite(const void *ptr, size_t size, size_t count, file *f);Hàm fwrite dùng để ghi hàng bit trong vùng ghi nhớ được quản lý bởi con trỏ ptr vào file đang rất được trỏ bởi vì f, kích cỡ là số bytes vẫn copy trường đoản cú vùng ghi nhớ của ptr và count là mốc giới hạn ghi vùng nhớ kia xuống file.

Hàm fwrite không thân thiết vùng ghi nhớ của chúng ta có format gì, nó quan lại tâm size vùng nhớ nên đọc cùng cứ vắt copy toàn bộ các bits và file, những lần sẽ copy 1 block of bit.

size_t fread(void *ptr, size_t size, size_t count, tệp tin *f);Hàm fread sẽ copy count lần block of bits có kích cỡ là size, gửi vào vùng nhớ được trỏ đến do ptr, từ bỏ file vẫn được quản lý bởi f.

Sau khi điện thoại tư vấn hàm fread, internal file position indicator sẽ dịch rời tới (size * count) bytes từ vị trí bắt đầu đọc file.

Ví dụ:

#include #include #include void writeToFile(FILE *file)char *s = "Hello everyone!";fwrite(s, strlen(s), 1, file);void readFromFile(FILE *file)void *ptr = operator new(255); //allocate 255 bytes on Heapfread(ptr, 255, 1, file);(static_cast(ptr))<255> = "";std::cout << static_cast(ptr) << std::endl;int main()const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "w+b"); //use binary modeif (!file)std::cout << "Can not mở cửa this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);fseek(file, 0, SEEK_SET);readFromFile(file);fclose(file);return 0;Chạy lịch trình trên cho ra hiệu quả là tương đối nhiều kí từ bỏ rác.

Như các bạn thấy, hàm fread gọi đúng 255 bytes vào file để mang vào vùng ghi nhớ của ptr nên các giá trị thừa xuất hiện. Trong trường phù hợp này, sử dụng hàm fread và fwrite không phù hợp. Hàm fread cùng fwrite hay được dùng để làm đọc và ghi tài liệu kiểu struct vào file.

Write & read structs

Mình vẫn duy trì nguyên cấu tạo chương trinh như trên cùng chỉ biến đổi code trong hàm writeToFile với readFromFile.

Trước hết, mình chế tạo một struct đơn giản như sau:

struct Employee__int32 ID;char name<50>;;Kích thước của struct này là 56 bytes (không phải là 54 bytes bởi vì cách tổ chức dữ liệu trong struct còn tương quan đến có mang struct alignment). Do vậy là từng unit bao gồm kiểu Employee được tạo nên đều chiếm phần một vùng ghi nhớ có kích thước 56 bytes.

Các chúng ta thử tưởng tượng nếu bọn họ sử dụng những hàm ghi tệp tin như fputs, fprintf... Thì kích cỡ tên của mọi người sẽ khác nhau dẫn đến họ không tất cả một định dạng bình thường để dễ làm chủ nhiều Employee trong file. Vấn đề đặt nó vào trong 1 struct giúp chúng ta đọc và ghi file dễ dãi hơn nhiều.

Xem thêm: Top 10 Người Sống Lâu Nhất Trong Lịch Sử, Tuổi Thọ Người

Dưới đấy là một đoạn chương trình chủng loại cho câu hỏi xử lý file để quản lý 3 Employee:

#include #include #include struct Employee__int32 ID;char name<50>;;Employee emps<3> = 1, "Le Tran Dat" , 2, "Ngo Doan Tuan" , 3, "Le Dinh Huy" ;void writeToFile(FILE *file)for (int i = 0; i < 3; i++)fwrite(&emps, sizeof(Employee), 1, file);void readFromFile(FILE *file)Employee emp;for (int i = 0; i < 3; i++)fread(&emp, sizeof(Employee), 1, file);std::cout << emp.ID << std::endl;std::cout << emp.name << std::endl;std::cout << "================================" << std::endl;int main()const char *filePath = "C:/Users/ADMIN/Desktop/my_document.txt";FILE *file;file = fopen(filePath, "w+b"); //use binary modeif (!file)std::cout << "Can not xuất hiện this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);fseek(file, 0, SEEK_SET);readFromFile(file);fclose(file);return 0;Các bạn chạy test đoạn chương trình trên để thấy kết quả.

Bây giờ chúng ta cùng mở tệp tin my_document.txt trong thư mục Desktop để thấy thử ngôn từ trong file như thế nào: