Ghi file trong C++ (fputc, fputs,fprintf) | Laptrinhcanban.com

Ghi file trong C++ (fputc, fputs,fprintf)

Cùng tìm hiểu về cách ghi file trong C++. Ngôn ngữ C++ kế thừa các hàm dùng để ghi file từ ngôn ngữ C như fputc, fputs, hay fprintf, và bạn sẽ học được cách sử dụng chúng để ghi file trong C sau bài học này.

Chúng ta có 3 phương pháp ghi file trong C++ bằng cách sử dụng các hàm kế thừa từ C như sau:

  • Ghi từng ký tự vào file bằng hàm fputc
  • Ghi từng dòng file trong C++ bằng hàm fputs
  • Ghi từng dòng file theo định dạng chỉ định bằng hàm fprintf

Bài viết này sẽ chú trọng về cách Ghi file trong C++. Về quy trình tổng quát xử lý file trong C++, hãy tham khảo tại bài sau:

Trước khi ghi file trong C++

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

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

Ở đây, mode ghi 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 để ghi file trong C++ như sau:

ModeXử lýChức năng
wMở để ghi đèXoá nội dung cũ và ghi đè nội dung mới
Nếu file không tồn tại thì tạo file mới
aMở để ghi chènGhi chèn nội dung mới vào cuối file
Nếu file không tồn tại thì tạo file mới
r+Mở để đọc và ghi đèCho phép cả đọc và ghi đè
Nếu file không tồn tại thì trả về NULL
w+Mở để đọc và ghi đèCho phép cả đọc và ghi đè
Nếu file không tồn tại thì tạo file mới
a+Mở để đọc và ghi chènCho phép cả đọc và ghi chèn
Nếu file không tồn tại thì tạo file mới

Ví dụ, nếu bạn chỉ muốn mở để ghi đè file, hãy dùng tới mode w như sau:

FILE * fp = NULL; 
fp = fopen("sample.txt", "w");

Hoặc nếu bạn muốn mở để ghi chèn file, hãy dùng tới mode a như sau:

FILE * fp = NULL; 
fp = fopen("sample.txt", "a");

Tuy nhiên nếu bạn muốn mở file và để vừa ghi và vừa ghi đè file đó, lúc này mode cần dùng để mở file không phải là mode w, mà sẽ là mode r+ chẳng hạn.

FILE * fp = NULL; 
fp = fopen("sample.txt", "r+");

Chi tiết về các mode ghi file cũng được trình bày đầy đủ trong bài Mở file trong C++.

Sau khi đã mở file thành công bằng một trong hai hàm trên, lúc này chúng ta đã có thể tiến hành ghi dữ liệu vào file trong C++ với các phương pháp sau đây.

Ghi ký tự vào file bằng hàm fputc

Hàm fputc trong C++ là một hàm có sẵn trong thư viện chuẩn, có tác dụng ghi từng ký tự vào file chỉ định. Tên hàm fputc được viết tắt bởi cụm từ file, put và character, được dịch theo tiếng Việt chính xác là hàm ghi từng ký tự vào file.

Chúng ta sử dụng hàm fputc trong C++ với cú pháp sau đây:

int fputc(int char, FILE * fp);

Trong đó:

  • fp là con trỏ của file cần ghi, được tạo ra từ việc mở file ở phần trên.
  • char là ký tự cần ghi vào file

Hàm fputc sẽ trả về ký tự đã được ghi vào file. Trong trường việc ghi file thất bại thì giá trị EOF sẽ được trả về.

Ví dụ cụ thể, chúng ta sẽ ghi dòng text Hello vào file trống sample.txt. Chúng ta sẽ dùng hàm fopen để mở file, sau đó ghi từng ký tự có trong dòng nội dung này vào file bằng hàm fputc như sau:

#include <iostream>
using namespace std;

int main()
{
FILE * fp = NULL;

fopen_s(&fp, "sample.txt", "w");

fputc('H', fp);
fputc('e', fp);
fputc('l', fp);
fputc('l', fp);
fputc('o', fp);
fputc('\n', fp);

fclose(fp);

return 0;
}

Kết quả, các ký tự trong chuỗi sẽ được lần lượt ghi vào file sample.txt như sau:

Hello

Ghi chuỗi vào file trong C++ bằng hàm fputs

Hàm fputs trong C++

Việc ghi từng ký tự vào file bằng hàm fputc thật là vất vả phải không nào? Đó là lý do mà hàm fputs với chức năng ghi chuỗi vào file đã được ra đời.

Hàm fputs trong C++ là một hàm có sẵn trong thư viện chuẩn, có tác dụng ghi từng chuỗi vào file chỉ định. Tên hàm fputs được viết tắt bởi cụm từ file, putstring, được dịch theo tiếng Việt chính xác là hàm ghi chuỗi vào file.

Chúng ta sử dụng hàm fputs trong C++ với cú pháp sau đây:

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

Trong đó:
  • fp là con trỏ của file cần ghi, được tạo ra từ việc mở file
  • str là con trỏ tới nơi lưu trữ chuỗi đã ghi từ dòng vào file. Thông thường chúng ta chỉ định str bằng một chuỗi.

Hàm fputs sẽ trả về 0 nếu việc ghi chuỗi vào file thành cônt. Trong trường hợp việc ghi file thất bại thì EOF sẽ được trả về.

Lưu ý là hàm fputs không tự động ghi ký tự xuống dòng \n sau khi đã ghi chuỗi, do đó khi muốn xuống dòng khi ghi chuỗi thì chúng ta phải tự điền ký tự \n vào vị trí cần xuống dòng trong chuỗi.

Ví dụ dùng hàm fputs để ghi chuỗi vào file trong C++

Ví dụ cụ thể, chúng ta sẽ ghi nội dung sau vào file trống Hello.txt.

Hello World!
I am Kiyoshi

Chúng ta sẽ dùng hàm fopen để mở file, sau đó ghi các chuỗi này vào file bằng hàm fputs như sau:

#include <iostream>
using namespace std;

int main()
{
FILE * fp = NULL;

fopen_s(&fp, "Hello.txt", "w");

fputs("Hello World!\nI am Kiyoshi", fp);

fclose(fp);

return 0;
}

Kết quả, chuỗi chỉ định sẽ được lần lượt ghi vào file sample.txt như sau:

Hello World!
I am Kiyoshi

Ghi dữ liệu vào file trong C++ theo định dạng bằng hàm fprintf

Hàm fprintf trong C++ là gì

Hàm fprintf trong C++ là một hàm có sẵn trong thư viện chuẩn, có tác dụng ghi dữ liệu vào file theo định dạng chỉ định.

Bằng cách sử dụng hàm fprintf, chúng ta có thể định dạng các dữ liệu thuộc nhiều kiểu khác nhau, và sau đó ghi chúng vào các file có định dạng cố định như file CSV, JSON chẳng hạn.

Chúng ta sử dụng hàm fprintf trong C++ với cú pháp sau đây:

int fprintf(fp, “fo1 fo2 fo3 … “, var1, var2, var3 …);

Trong đó

  • fp là con trỏ của file cần ghi, được tạo ra từ việc mở file ở phần trên.
  • Các cặp fovar tương ứng là định dạng (format) ghi vào file của dữ liệu, và tên biến chứa dữ liệu đó.

Cơ chế hoạt động của hàm fprintf là lấy dữ liệu từ biến var, định dạng nó theo định dạng ghi trong fo để tạo ra một chuỗi. Sau đó thì ghi chuỗi vừa tạo này vào file mà con trỏ fp chỉ đến.

Hàm fprintf sẽ trả về một số thuộc kiểu int, chính là số ký tự có trong chuỗi được tạo. Trong trường hợp việc ghi file thất bại thì giá trị EOF sẽ được trả về.

Định dạng dữ liệu sử dụng trong hàm fprintf

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

Định dạng chuyển đổiKiểu biếnChi tiết
%hhdchar
unsigned char
Chuyển về dạng thập phân và lưu trữ trong biến 1 byte
%hdshort
unsigned short
Chuyển về dạng thập phân và lưu trữ trong biến 2 byte
%dint
unsigned int
Chuyển về dạng thập phân và lưu trữ trong biến kiểu int
%ldlong
unsigned long
Chuyển về dạng thập phân và lưu trữ trong biến 4 byte
%hhxchar
unsigned char
Chuyển về hệ thập lục phân và lưu trữ trong biến 1 byte
%hxshort
unsigned short
Chuyển về hệ thập lục phân và lưu trữ trong biến 2 byte
%xint
unsigned int
Chuyển về hệ thập lục phân và lưu trữ trong biến kiểu int
%lxlong
unsigned long
Chuyển về hệ thập lục phân và lưu trữ trong biến 4 byte
%ffloatChuyển về số thực dấu phẩy động và lưu trữ trong biến kiểu float
%lfdoubleChuyển về số thực dấu phẩy động và lưu trữ trong biến kiểu double
%ccharChuyển về 1 ký tự và lưu trữ trong biến kiểu char
%schar *Chuyển về chuỗi ký tự và lưu trữ trong biến kiểu mảng char
%pvoid *Chuyển về địa chỉ và lưu trữ trong con trỏ

Ví dụ ghi dữ liệu vào file trong C++

Giả sử chúng ta có các kiểu thông tin như [chuỗi], [ký tự] và [số] được lưu vào các biến tương ứng. Bằng cách sử dụng hàm fprintf, chúng ta có thể định dạng các thông tin này và ghi vào file như chương trình sau đây:

#include <iostream>
using namespace std;

int main()
{
FILE * fp = NULL;

char name[] = "Kiyoshi";
char sex = 'M';
int old = 30;

fopen_s(&fp, "user.txt", "w");

// Ghi dữ liệu theo định dạng chỉ định vào file
fprintf(fp, "%s %c %d\n", name, sex, old);
fprintf(fp, "%s,%c,%d\n", name, sex, old);
fprintf(fp, "name: %s, sex: %c, old: %d\n", name, sex, old);
fclose(fp);

return 0;
}

Kết quả, các dữ liệu với định dạng chỉ định sẽ được vào file Hello.txt như sau:

Kiyoshi M 30
Kiyoshi,M,30
name: Kiyoshi, sex: M, old: 30

Giống như thế, các kiểu thông tin như [chuỗi], [ký tự] và [số] sẽ được ghi theo định dạng chỉ định vào file.

Ghi mảng vào file trong C++

Ứng dụng hàm fprintf, chúng ta có thể thực hiện ghi mảng vào file trong C++.

Do các phần tử trong mảng C++ đều có cùng kiểu dữ liệu, nên chúng ta có thể chỉ định cùng kiểu định dạng để ghi các phần tử từ mảng vào file bằng hàm hàm fprintf. Ví dụ cụ thể:

#include <iostream>
using namespace std;

int main()
{
FILE * fp = NULL;

int num[] = {10, 20, 44, 60, 82};

fopen_s(&fp, "num.txt", "w");

// Ghi dữ liệu theo định dạng chỉ định vào file

fprintf(fp, "%d %d %d %d %d", num[0], num[1], num[2], num[3], num[4]);

fclose(fp);

return 0;
}

Kết quả, nội dung mảng sẽ được ghi vào file như sau:

10 20 44 60 82

Một cách tương tự thì chúng ta cũng có thể ghi các mảng 2 chiều vào file trong C++. Khi đó mỗi mảng con 1 chiều trong mảng 2 chiều sẽ được coi như một dòng để ghi vào file, và chúng ta cần phải thêm ký tự xuống dòng \n khi ghi từng mảng dòng vào file như sau:

#include <iostream>
using namespace std;

int main()
{
FILE * fp = NULL;

int bangdiem[][3] = {
{7, 9, 8} ,
{8, 6, 7} ,
{5, 7, 6} ,
{4, 9, 5} ,
{5, 8, 7} ,
{6, 9, 3}
} ;
//Lấy độ dài của mảng 2 chiều
int y = sizeof(bangdiem) / sizeof(bangdiem[0]);
int x = sizeof(bangdiem[0]) / sizeof(bangdiem[0][0]);

fopen_s(&fp, "bangdiem.txt", "w");

// Ghi từng mảng 1 chiều trong mảng 2 chiều vào file
for (int i = 0; i < y; i++){
fprintf(fp, "Toan: %d Van: %d Anh: %d\n", bangdiem[i][0], bangdiem[i][1], bangdiem[i][2]);
}

fclose(fp);

return 0;
}

Kết quả, từng dòng sẽ được ghi vào file như sau:

Toan: 7 Van: 9 Anh: 8
Toan: 8 Van: 6 Anh: 7
Toan: 5 Van: 7 Anh: 6
Toan: 4 Van: 9 Anh: 5
Toan: 5 Van: 8 Anh: 7
Toan: 6 Van: 9 Anh: 3

Ghi cấu trúc vào file trong C++

Ứng dụng hàm fprintf, chúng ta có thể thực hiện ghi cấu trúc vào file trong C++.

Do các thành viên trong cấu trúc C++ có thể có kiểu dữ liệu khác nhau, nên chúng ta cần chỉ định kiểu định dạng phù hợp cho từng thành viên để ghi giá trị của chúng từ mảng vào file bằng hàm hàm fprintf.

Ví dụ chúng ta ghi dữ liệu từ mảng cấu trúc vào file trong C++ bằng hàm fprintf như sau:

#include <iostream>
using namespace std;

#define PERSON_NUM 5

//Khai báo kiểu struct
typedef struct {
char name[20];
char sex;
int age;
double height;
double weight;
} person_t;

int main()
{
//Khởi tạo thực thể struct là một mảng struct
person_t p[PERSON_NUM] = {{"Bob", 'M', 19, 165.4, 72.5},
{"Alice", 'F', 19, 161.7, 44.2},
{"Tom", 'M', 20, 175.2, 66.3},
{"Stefany", 'F', 18, 159.3, 48.5},
{"Leonardo", 'M', 19, 172.8, 67.2}};
//Tạo con trỏ file
FILE * fp = NULL;

//Mở file
fopen_s(&fp, "people.txt", "w");

//Ghi header vào file
fprintf(fp, "%s %s %s %s %s\n", "name", "sex", "age", "height", "weight");

// Ghi từng thực thể của cấu trúc như một dòng vào file
for (short i = 0; i < PERSON_NUM; i++) {
fprintf(fp, "%s %c %d %.2f %.2f \n",p[i].name, p[i].sex,p[i].age,p[i].height,p[i].weight);
}

fclose(fp);

return 0;
}

Kết quả, nội dung mảng cấu trúc sẽ được ghi vào file như sau:

name sex age height weight
Bob M 19 165.40 72.50
Alice F 19 161.70 44.20
Tom M 20 175.20 66.30
Stefany F 18 159.30 48.50
Leonardo M 19 172.80 67.20

Ghi file CSV trong C++

Ở phần trên, chúng ta đã tiến hành ghi nội dung các kiểu dữ liệu phức tạp như mảng hay cấu trúc vào file dưới dạng file txt rồi. Tuy nhiên chúng ta cũng có thể ghi dữ liệu trên vào file CSV trong C++, đơn giản bằng cách thay đổi đuôi file từ .txt sang .csv là xong.

Ví dụ cụ thể, chúng ta ghi dữ liệu từ mảng cấu trúc vào file CSV trong C++ bằng hàm fprintf như sau. Lưu ý là chúng ta cần viết định dạng các dữ liệu cách nhau bởi dấu phẩy để có thể ghi từng dữ liệu vào từng ô trong file CSV.

#include <iostream>
using namespace std;

#define PERSON_NUM 5

typedef struct {
char name[20];
char sex;
int age;
double height;
double weight;
} person_t;

int main()
{

person_t p[PERSON_NUM] = {{"Bob", 'M', 19, 165.4, 72.5},
{"Alice", 'F', 19, 161.7, 44.2},
{"Tom", 'M', 20, 175.2, 66.3},
{"Stefany", 'F', 18, 159.3, 48.5},
{"Leonardo", 'M', 19, 172.8, 67.2}};

FILE * fp = NULL;

int num[] = {10, 20, 44, 60, 82};

fopen_s(&fp, "people.csv", "w");

// Ghi từng mảng 1 chiều trong mảng 2 chiều vào file
fprintf(fp, "%s,%s,%s,%s,%s\n", "name", "sex", "age", "height", "weight");
for (short i = 0; i < PERSON_NUM; i++) {
fprintf(fp, "%s,%c,%d,%.2f,%.2f\n",p[i].name, p[i].sex,p[i].age,p[i].height,p[i].weight);
}



fclose(fp);

return 0;
}

Kết quả, nội dung mảng cấu trúc sẽ được ghi vào file people.csv như sau:
Ghi vào file CSV trong C++

Tổng kết

Trên đây Kiyoshi đã hướng dẫn các bạn về cách ghi file trong C++ rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về C++ trong các bài học tiếp theo.

HOME>> >>

Profile
きよしです!笑

Tác giả : Kiyoshi (Chis Thanh)

Kiyoshi là một cựu du học sinh tại Nhật Bản. Sau khi tốt nghiệp đại học Toyama năm 2017, Kiyoshi hiện đang làm BrSE tại Tokyo, Nhật Bản.