Đọc file trong C++ bằng fstream | Laptrinhcanban.com

Đọc file trong C++ bằng fstream

Cùng tìm hiểu về cách đọc file trong C++. Ngoài cách dùng các hàm được kế thừa từ ngôn ngữ C thì chúng ta cũng có thể đọc file trong C++ bằng các phương pháp mới được tích hợp trong header file fstream, ví dụ như sử dụng toán tử >>, hoặc là hàm getline() trong C++, và bạn sẽ làm chủ được chúng sau bài học này.

Chúng ta có 2 phương pháp đọc file trong C++ bằng cách sử dụng header file fstream như sau:

  • Đọc file trong C++ bằng toán tử >>
  • Đọc file trong C++ bằng hàm getline

Ứng dụng các phương pháp này, chúng ta cũng có thể:

  • Đọc từng ký tự trong file bằng C++
  • Đọc từng dòng trong file bằng C++
  • Đọc từng từ trong file bằng C++
  • Đọc file CSV trong C++

Lại nữa, ngoài cách sử dụng header file fstream thì bạn cũng có thể sử dụng các hàm kế thừa từ ngôn ngữ C để đọc file trong C++.

Trước khi đọc file trong C++

Để đọc file trong C++, bạn cần phải tạo ra một stream chứa thông tin file bằng cách sử dụng class fstream hoặc ifstream mà Kiyoshi đã hướng dẫn trong bài fstream, ifstream và ofstream trong C++.

Tuy nhiên do class fstream bao gồm cả class ifstream và có khả năng vừa đọc vừa ghi file, nên thông thường chúng ta sẽ chọn class này để tạo ra stream chứa thông tin file cần đọc.

Ví dụ cụ thể, chúng ta include header file fstream và mở file trong C++ bằng ifstream như sau:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
//Mở file bằng ifstream
ifstream ifs("test.txt");
}

Sau khi đã mở file thành công bằng ifstream, một stream ifs chứa thông tin file đã được tạo ra, và lúc này chúng ta đã có thể tiến hành đọc dữ liệu từ file trong C++ bằng cách thao tác với stream này với các phương pháp sau đây:

Đọc file trong C++ bằng toán tử >> trong ifstream

Toán tử >> trong ifstream

Toán tử >> trong ifstream được sử dụng để gán từng nội dung đọc từ file vào một biến, hoặc một chuỗi chỉ định.
Cú pháp sử dụng toán tử >> để đọc file trong C++ như sau:

ifstream ifs >> variable;

Trong đó ifs là luồng chứa file được tạo ra khi mở file bằng ifstream, và variable là một biến kiểu string hoặc char để lưu dữ liệu đọc từ file ra.
Nếu chỉ định variable là một biến thuộc kiểu string thì chúng ta có thể đọc được từng từ trong file. Và nếu chỉ định variable là một biến thuộc kiểu char thì chúng ta có thể đọc được từng ký tự trong file.

Lưu ý, toán tử >> trong ifstream chỉ có thể đọc từng từ hoặc từng ký tự từ file trong C++, do đó chúng ta cần sử dụng toán tử này kết hợp với một vòng lặp để có thể đọc toàn bộ dữ liệu trong file.

Đọc từng ký tự trong file bằng toán tử >>

Chúng ta chỉ định variable là một biến thuộc kiểu char để đọc từng ký tự trong file bằng toán tử >>.

Ví dụ cụ thể, chúng ta có file sample.txt với nội dung sau đây:

123abc  

Chúng ta sẽ đọc từng ký tự từ file này và xuất ra màn hình bằng cách sử dụng toán tử >> trong C++ như sau:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
//Mở file bằng ifstream
ifstream ifs("sample.txt");
//Kiểm tra file đã mở thành công hay chưa
if(!ifs){
cerr << "Error: file not opened." << endl;
return 1;
}

//Khai báo biến kiểu char để lưu ký tự đọc được
char chr;

//Đọc và in lần lượt các ký tự trong file
while(ifs >> chr){
cout << chr << endl;
}

//Đóng file
ifs.close();
return 0;
}

Kết quả:

1
2
3
a
b
c

Đọc từng từ trong file bằng toán tử >>

Chúng ta chỉ định variable là một biến thuộc kiểu string để đọc từng ký tự trong file bằng toán tử >>.

Ví dụ cụ thể, chúng ta có file sample.txt với nội dung sau đây:

I am a big big girl!

Chúng ta sẽ dùng ifstream để mở file, sau đó đọc từng ký tự từ file này và xuất ra màn hình bằng cách sử dụng toán tử >> trong C++ như sau:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
//Mở file bằng ifstream
ifstream ifs("sample.txt");
//Kiểm tra file đã mở thành công hay chưa
if(!ifs){
cerr << "Error: file not opened." << endl;
return 1;
}

//Khai báo biến kiểu string để lưu từng từ đọc được
string str;

//Đọc và in lần lượt các từ trong file
while(ifs >> str){
cout << str << endl;
}

//Đóng file
ifs.close();
return 0;
}

Kết quả:

I
am
a
big
big
girl!

Đọc file trong C++ bằng bằng hàm getline

Hàm getline() trong C++

Hàm getline() trong C++ là một hàm có sẵn trong thư viện chuẩn, có tác dụng đọc từng dòng trong file chỉ định. Hàm getline đọc liên tục các ký tự từ file và lưu trữ nó trong một chuỗi cho đến khi nó tìm thấy ký tự phân cách. Chúng ta có thể chỉ định ký tự phân cách này, và giá trị mặc định của ký tự phân cách là ký tự xuống dòng \n.

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

std::getline(input, str, delimiter )

Trong đó:

  • input là luồng chứa file được tạo ra khi mở file bằng ifstream
  • str là chuỗi để lưu kết quả đọc file
  • delimiter là ký tự phân cách, và chúng ta có thể lược bỏ đối số này khi muốn sử dụng ký tự phân cách mặc định là ký tự xuống dòng \n.

Hàm getline sẽ trả về chuỗi đọc được, và trong trường hợp đọc file thất bại, giá trị 0 sẽ được trả về.

Do ký tự phân cách mặc định của hàm getline là ký tự xuống dòng \n nên chúng ta hay dùng hàm này để đọc từng dòng file trong C++. Tuy nhiên bằng cách chỉ định ký tự phân cách, chúng ta cũng có thể đọc file theo nhiều cách khác nhau.

Cũng giống như các hàm trong thư viện chuẩn khác thì để sử dụng hàm getline, chúng ta thường phải viết kèm namespace là std vào trước tên hàm như sau:

std::getline();

Tuy nhiên chúng ta cũng có thể rút gọn tên của namespace này bằng cách chỉ định namespace đầu chương trình:

using namespace std;

getline();

Lưu ý, hàm getline chỉ có thể đọc từng dòng file trong C++, do đó chúng ta cần sử dụng hàm này kết hợp với một vòng lặp để có thể đọc toàn bộ các dòng trong file.

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

Khi lược bỏ đối số delimiter trong hàm getline, khi đó hàm sẽ sử dụng ký tự phân cách mặc định là ký tự xuống dòng \, và chúng ta có thể sử dụng hàm getline để đọc từng dòng file trong C++.

Ví dụ cụ thể, chúng ta có file sample.txt với nội dung sau đây:

1234567
89abc
def

Chúng ta sẽ dùng ifstream để mở file, sau đó đọc từng dòng trong file bằng hàm getline như sau. Lưu ý là chúng ta sử dụng vòng lặp while để có thể chạy số lần hàm getline tương ứng với số dòng cần đọc, và sử dụng vector để lưu lần lượt các dòng đọc được vào bộ nhớ.

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{

string filename("sample.txt");
// Khai báo vector để lưu các dòng đọc được
vector<string> lines;
string line;

//Mở file bằng ifstream
ifstream input_file(filename);
//Kiểm tra file đã mở thành công chưa
if (!input_file.is_open()) {
cerr << "Could not open the file - '"
<< filename << "'" << endl;
return EXIT_FAILURE;
}

//Đọc từng dòng trong
while (getline(input_file, line)){
lines.push_back(line);//Lưu từng dòng như một phần tử vào vector lines.
}

//Xuất từng dòng từ lines và in ra màn hình
for (const auto &i : lines)
cout << i << endl;

//Đóng file
input_file.close();
return 0;
}

Kết quả:

1234567
89abc
def

Đọc từng từ trong file bằng hàm getline

Khi chỉ định đối số delimiter trong hàm getline, khi đó hàm sẽ sử dụng ký tự phân cách chỉ định này, và chúng ta có thể sử dụng hàm getline để đọc từng từ trong file.

Ví dụ cụ thể, chúng ta có file sample.txt với nội dung sau đây:

I am a big big girl!

Các từ trong file này được phân cách bởi ký tự trống (dấu cách), do vậy nếu chỉ định đối số delimiter trong hàm getline bằng ký tự trống ' ', chúng ta có thể đọc từng từ trong file bằng hàm getline như sau:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{

string filename("sample.txt");
// Khai báo vector để lưu các dòng đọc được
vector<string> lines;
string line;

//Mở file bằng ifstream
ifstream input_file(filename);
//Kiểm tra file đã mở thành công chưa
if (!input_file.is_open()) {
cerr << "Could not open the file - '"
<< filename << "'" << endl;
return EXIT_FAILURE;
}

//Đọc từng từ trong file phân cách bởi ký tự trống
while (getline(input_file, line, ' ')){
lines.push_back(line);//Lưu từng dòng như một phần tử vào vector lines.
}

//Xuất từng dòng từ lines và in ra màn hình
for (const auto &i : lines)
cout << i << endl;

//Đóng file
input_file.close();
return 0;
}

Kết quả:

I
am
a
big
big
girl!

Đọ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.

Và để đọc các file có định dạng cố định như thế này thì chúng ta có thể dùng hàm getline mà Kiyoshi đã giới thiệu ở trên. Chúng ta có thể lựa chọn việc đọc từng ký tự, đọc từng từ, hoặc đọc từng dòng ra từ file CSV tương tự như với các loại file khác.

Sau đây, hãy cùng tìm hiểu cách dùng hàm getline để đọc file csv trong C++ nhé.

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

Giả sử chúng ta có file test.csv với nội dung 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

Chúng ta sẽ mở file này và đọc từng ô trong file CSV theo định dạng như sau:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{

string filename("test.csv");
// Khai báo vector để lưu các dòng đọc được
vector<string> lines;
string line;

//Mở file bằng ifstream
ifstream input_file(filename);
//Kiểm tra file đã mở thành công chưa
if (!input_file.is_open()) {
cerr << "Could not open the file - '"
<< filename << "'" << endl;
return EXIT_FAILURE;
}

//Đọc từng dòng trong
while (getline(input_file, line, ' ')){
lines.push_back(line);//Lưu từng dòng như một phần tử vào vector lines.
}

//Xuất từng dòng từ lines và in ra màn hình
for (const auto &i : lines)
cout << i << endl;

//Đóng file
input_file.close();
return 0;
}

Và kết quả:

test01
1.0
1.1
1.2
test02
2.0
2.1
2.2
test03
3.0
3.1
3.2

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à 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 tách bởi dấu phẩy

Giả sử chúng ta có file test.csv với nội dung 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 tự thì chúng ta cũng mở file này và đọc từng ô trong file CSV theo định dạng như sau:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{

string filename("test.csv");
// Khai báo vector để lưu các dòng đọc được
vector<string> lines;
string line;

//Mở file bằng ifstream
ifstream input_file(filename);
//Kiểm tra file đã mở thành công chưa
if (!input_file.is_open()) {
cerr << "Could not open the file - '"
<< filename << "'" << endl;
return EXIT_FAILURE;
}

//Đọc từng dòng trong
while (getline(input_file, line, ',')){
lines.push_back(line);//Lưu từng dòng như một phần tử vào vector lines.
}

//Xuất từng dòng từ lines và in ra màn hình
for (const auto &i : lines)
cout << i << endl;

//Đóng file
input_file.close();
return 0;
}

Và kết quả:

test01
1.0
1.1
1.2
test02
2.0
2.1
2.2
test03
3.0
3.1
3.2

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à 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.

Tổng kết

Trên đây Kiyoshi đã hướng dẫn các bạn về cách đọc 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.