Chào chúng ta đang theo dõi khóa huấn luyện lập trình trực tuyến ngôn từ C++.

Bạn đang xem: Đọc và ghi file trong c++

Trong bài học kinh nghiệm này, họ sẽ cùng khám phá về các khái niệm về tệp tin và phương pháp để thao tác với tệp tin trong ngôn từ 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 ngẫu nhiên thiết bị tàng trữ nào thì cứng cáp chắn các bạn đã từng thao tác làm việc với File. Khi các bạn 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ữ trong File để khi lịch trình game bị tắt đi thì chúng ta không nên chơi lại trường đoản cú đầu. Khi chúng ta cài đặt cấu hình cho 1 phần mềm cùng tắt đi, thông số kỹ thuật đó được lưu lại vào File nhằm lần thao tác tiếp theo đang sử dụng. Tốt khi chúng ta biên dịch một công tác C++ bên trên Visual Studio 2015, C++ Compiler của Visual studio vẫn đọc mã nguồn chúng ta đã viết trong các file *.daihoangde.vn để bình chọn lỗi cùng dịch bọn chúng sang tệp tin *.obj. Ngay cả hệ điều hành Windows mà chúng ta đang thực hiện cũng là tập hợp của nhiều file được lưu giữ trữ phía bên trong phân vùng ổ đĩa cần sử dụng cho Hệ điều hành...

Đó là 1 trong vài ví dụ cho thấy sự sống thọ của tệp tin trong đồ vật tính. Vậy thì bọn họ đã thao tác với gần như File đó như thế nào?

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

Theo quan niệm 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 đồ vật tính.

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

Trong ngữ điệu lập trình C/C++: file là kiểu dáng đối tượng, nó xác minh một stream cùng chứa những thông tin quan trọng để điều khiển, gồm 1 con trỏ trỏ cho buffer của nó, những chỉ mục với trạng thái của nó.

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

Để các bạn không bị nhầm lẫn, bản thân đang nói tới kiểu dữ liệu FILE được khái niệm trong thư viện cstdio (hay stdio.h) mà gồm thể các bạn đã từng học tập trong ngữ điệu C. Họ sẽ học cách sử dụng các Stream để thao tác với file cố kỉnh vì sử dụng kiểu dữ liệu FILE trong số bài học sau, nhưng lại mình nghĩ kiểu tài liệu FILE trong tủ sách cstdio cũng có thể có những điểm mạnh riêng của nó nên mình không vứt qua bài học này.

Làm việc với tệp tin type trong C/C++

Trong bài học này, mình đang hướng dẫn chúng ta thực hiện nay các thao tác làm việc như mở file, đọc với ghi tài liệu trong file... Bọn họ cần thao tác trên một file cụ thể nào đó bắt buộc mình sẽ tạo nên một tệp tin với tên file là my_document.txt trong thư mục Desktop có đường truyền trên sản phẩm mình là: C:/Users/ADMIN/Desktop/my_document.txt

Để thao tác với file, bọn họ cần biết địa điểm của file (thông qua con đường dẫn) để bé trỏ hình trạng FILE có thể tạo được luồng tài liệu giữa người dùng và file trên vật dụng 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 bạn có thể sử dụng hàm fopen được tư tưởng trong thư viện cstdio:

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


*

Nếu mở file thành công, một địa chỉ cửa hàng của một đối tượng người dùng kiểu FILE sẽ tiến hành trả về. Trường hợp mở file thua kém 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 open this file" << std::endl;elsestd::cout << "File is opened" << std::endl;Trong đoạn lịch trình trên, mình mở tệp tin đã chế tác sẵn trong thư mục Desktop cùng với mode "r" (chỉ dùng để làm đọc dữ liệu).

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

File văn bản là phần lớn file mà lại các bạn cũng có thể đọc được khi mở bằng những trình soạn thảo văn bản, thông thường những tệp tin này được định hình Unicode (hoặc hầu như định dạng dùng cho văn phiên bản khác).

File bị mã hóa (thường điện thoại tư vấn là tệp tin nhị phân) bắt buộc đọc được khi mở tệp tin bằng các trình soạn thảo văn bản. áp dụng File bị mã hóa giúp chúng ta bảo mật dữ liệu tốt hơn file văn bản.

Các mode mà tôi đã liệt kê sinh hoạt bảng trên chỉ dùng để làm thao tác với file văn bản. Khi thao tác làm việc với tệp tin bị mã hóa (file nhị phân), chúng ta cần nối thêm kí từ bỏ 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 thao tác với file xong, các bạn cần đóng góp file lại để tránh hầu hết lỗi phạt sinh bên cạnh ý muốn. Để đóng file, bọn họ sử dụng hàm fclose:

int fclose(FILE *file);Trong đó, tệp tin là nhỏ trỏ được dùng để lưu trữ địa chỉ cửa hàng của đối tượng FILE sẽ mở. Nếu đóng góp 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 mở cửa this file" << std::endl;elsestd::cout << "File is opened" << std::endl;fclose(file);Hàm fclose sẽ giải phóng tất cả dữ liệu chưa được xử lý trên tệp tin nếu chúng vẫn còn đấy lưu vào buffer, đóng file lại, cùng giải phóng toàn khu vực nhớ mà đối tượng FILE sử dụng.

Write data khổng lồ file

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

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

void writeToFile(FILE *file);Hàm này sẽ được gọi sau khoản thời gian mở tệp tin 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 open this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);fclose(file);Bây giờ, bọn họ chỉ cân nhắc nội dung bên trong hàm writeToFile.

Để ghi tài liệu vào file, bọn họ có những hàm sẽ được tư tưởng sẵn trong tủ sách cstdio như sau:

fputc:

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

Ví dụ:

void writeToFile(FILE *file)int c = fputc("A", file);std::cout << c << std::endl;Sau khi chạy chương trình xong, các bạn mở file my_document.txt trên Desktop lên vẫn thấy kí từ bỏ "A" đã có được ghi vào, bên cạnh đó 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ỏ đến bởi bé trỏ f cho tới khi gặp kí tự "".

Ví dụ:

void writeToFile(FILE *file)int c = fputs("hello", file);Sau lúc chạy chương trình, các bạn mở file my_document.txt nghỉ ngơi thư mục Desktop đã thấy kí tự "A" cơ hội nãy không còn nữa, cố kỉnh vào đó là chuỗi kí tự "hello".

Read data from file

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

void readFromFile(FILE *file)//read dataĐể làm các ví dụ vào phần này, bản thân sẽ điện thoại tư vấn hàm này sau khi đã điện thoại tư vấn 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ở để vừa đọc với ghi file, buộc phải mình sẽ áp dụng mode "w+" (hoặc "r+").

Và dưới đây là một số hàm được tư tưởng sẵn trong tủ sách cstdio hỗ trợ chúng ta đọc dữ 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 file position indicator sẽ chuyển mang lại kí từ tiếp theo. Quý giá trả về là mã ASCII của kí tự sẽ đọc được.

Ví dụ:

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

char* fgets(char *buf, int n, tệp tin *f);Hàm fgets gọi từ file ra (n - 1) kí tự, việc đọc dữ liệu có khả năng sẽ bị dừng nếu gọi được kí từ new line " " hoặc EOF. Chuỗi kí tự hiểu được vẫn lưu vào vùng nhớ được quản lý bởi bé trỏ buf, nếu đọc dữ liệu thành công xuất sắc thì trả về địa chỉ của buf, ngược 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ả gọi file được lưu vào mảng kí trường đoản cú str.

Reposition stream position indicator

Ghép những ví dụ nghỉ ngơi trên lại, họ có một chương trình đơn giản minh họa cho việc ghi file và đọc từng dòng tài liệu (line by line) đã được ghi vào file 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 mở cửa this file" << std::endl;elsestd::cout << "File is opened" << std::endl;writeToFile(file);readFromFile(file);fclose(file);return 0;Tuy nhiên, hiệu quả cho ra màn hình không phải 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, câu hỏi ghi tệp tin đã khiến internal file position indicator trỏ mang lại vị trí cuối cùng trong file. Sau khoản thời gian quay trở lại hàm main, họ tiếp tục gọi hàm readFromFile với một con trỏ file. Như vậy, lúc chúng ta đọc tệp tin thì bọn họ lại ban đầu đọc trên vị trí hoàn thành file.

Để hạn chế và khắc phục điều này, họ cần đóng bé trỏ file lại với mở tạo một liên kết mới bởi hàm fopen với mode dùng để làm đọc file. Tuy nhiên, làm bởi vậy thì code giải pháp xử lý của bọn họ sẽ lâu năm hơn. Thư viện cstdio đã hỗ trợ cho chúng ta hàm fseek để chuyển đổi vị trí trỏ mang lại trong file của internal tệp tin position indicator.

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

f là con trỏ trỏ đến đối tượng người tiêu dùng FILE sẽ mở.

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

origin là vị trí đặt nhỏ trỏ vào file:

*

Như vậy, sau khoản thời gian gọi hàm writeToFile xong, bọn họ cần dịch rời 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 đó chạy công tác thì thấy dữ liệu in ra màn hình hiển thị đúng tựa như các gì họ đã ghi vào file.

Determine form size of nội dung of file

Đôi khi chúng ta cần đọc toàn cục nội dung của file vào trong 1 vùng lưu giữ trên Heap, bọn họ sẽ cần biết trước kích thước nội dung gồm trong file để cấp phép đủ vùng nhớ trước lúc đọc file. Tủ sách cstdio chỉ cung cấp cho họ hàm ftell:

long int ftell(FILE *f);Hàm này sẽ trả về địa điểm của file indicator đã trỏ mang lại trong tệp tin (số bytes của văn bản file mà lại indicator đã để mắt tới qua).

Như vậy, các bạn cũng có thể đọc size của ngôn từ trong file bằng cách dịch internal tệp tin position indicator về vị trí ở đầu cuối trong file rồi call 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 để đọc và ghi tài liệu chỉ 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 làm 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ỏ do f, form size là số bytes sẽ copy trường đoản cú vùng ghi nhớ của ptr cùng count là mốc giới hạn ghi vùng nhớ đó xuống file.

Hàm fwrite không nhiệt tình vùng ghi nhớ của các bạn có định hình gì, nó quan lại tâm form size vùng nhớ phải đọc và cứ cụ copy tất cả 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 vẫn copy count lần block of bits có size là size, đưa vào vùng lưu giữ được trỏ đến do ptr, trường đoản cú file đã được thống trị bởi f.

Sau khi call hàm fread, internal file position indicator sẽ dịch chuyển 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 mang đến ra tác dụng là không hề ít kí từ rác.

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

Write và read structs

Mình vẫn giữ nguyên cấu trúc chương trinh như trên và chỉ biến hóa code trong hàm writeToFile với readFromFile.

Trước hết, mình chế tạo một struct dễ dàng như sau:

struct Employee__int32 ID;char name<50>;;Kích thước của struct này là 56 bytes (không đề xuất là 54 bytes bởi vì cách tổ chức triển khai dữ liệu vào struct còn liên quan đến khái niệm struct alignment). Vì thế là mỗi unit có kiểu Employee được tạo thành đều chỉ chiếm một vùng nhớ có form size 56 bytes.

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

Xem thêm: Chuyển File Pdf Sang Powerpoint Trực Tuyến, Chuyển Pdf Thành Ppt Miễn Phí

Dưới đó là một đoạn chương trình mẫu mã cho vấn đề 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 open 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 demo đoạn chương trình trên giúp thấy kết quả.

Bây giờ họ cùng mở tệp tin my_document.txt trong folder Desktop để thấy thử văn bản trong file như vậy nào: