Chuyển đến nội dung chính

C/C++: file








Open file thư viện cstdio:

FILE* fopen(const char *file, const char *mode); int fclose(FILE *file); 

Ghi tới một file trong C

Dưới đây là hàm đơn giản nhất để thực hiện việc ghi các ký tự riêng tới một luồng:
int fputc( int c, FILE *fp );

Đọc file trong C

Dưới đây là hàm đơn giản nhất để đọc một ký tự riêng rẽ từ file:
int fgetc( FILE * fp );
fputs:
int fputs(const char *str, FILE *f);
Hàm fputs ghi một C-Style string vào file được trỏ đến bởi con trỏ f cho đến khi gặp kí tự '\0'.
fprintf:
int fprintf(FILE *f, const char *format, ...);
Hàm fprintf tương tự hàm printf trong ngôn ngữ C. Tuy nhiên, hàm printf được mặc định liên kết với đối tượng FILE có tên là stdout nên sử dụng hàm printf sẽ ghi nội dung ra màn hình.
Hàm printf tương đương với cách sử dụng fprintf(stdout, format, ...).
Và dưới đây là một số hàm được định nghĩa sẵn trong thư viện cstdio hỗ trợ chúng ta đọc dữ liệu văn bản từ file.
  • fgetc: int fgetc(FILE *f); Hàm fgetc đọc ra một kí tự trong file, internal file position indicator sẽ chuyển đến kí tự tiếp theo. Giá trị trả về là mã ASCII của kí tự đã đọc được.
char *fgets( char *buf, int n, FILE *fp );
Hàm fgets() đọc n-1 ký tự từ một luồng vào tham chiếu bởi fp. Nó copy chuỗi đọc đến bộ đệm buf, gán ký tự null vào kết thúc chuỗi.

TRONG C++:

Trong C++ thì ta có 3 loại File stream cơ bản sau :
ifstream : Dùng cho file nhập vào. Loại này chỉ có thể được dùng để đọc dữ liệu vào file vào bộ nhớ mà thôi.
ofstream : Dùng cho file xuất ra. Loại này thì có thể dùng để tạo ra files và chép dữ liệu vào chúng.
fstream : Đây là kênh file.(File stream). Loại này thì có thể vừa tạo file, vừa ghi dữ liệu vào file và đọc dữ dữ liệu từ file vào luôn.
1.Cách sử dụng fstream
1.1.Đối với file văn bản (File dạng *.txt)
Để định nghĩa 1 đối tượng file ta dùng cú pháp sau : fstream dataFile 
Ở đây dataFile chỉ là tên biến do người dùng đặt ra.
Để mở 1 file ta dùng cú pháp sau :
fstream  <Tên biến tệp> (<Tên tệp>, <chế độ mở tệp>);
Hoặc:
fstream  <Tên biến tệp>;
 <Tên biến tệp>.open(<Tên tệp>, <chế độ mở tệp>);
Ví dụ :  fstream dataFile; 
dataFile.open("info.txt", ios::out); // hoặc fstream fread ("E: \\data.txt", ios :: in); 
           
Trong đó :
-       đối_số_1là 1 chuỗi tên chứa tên file hoặc đường dẫn dẫn đến file
-       đối_số_2 là 1 flag của file và cái này cho ta biết chế độ nào mà chúng ta dùng để mở file.
Ở ví dụ trên thì tên file là info.txt còn flag file ở đây là ios::out. Điều này, cho C++ biết chúng ta mở file ở chế độ xuất ra. Chế độ xuất ra cho phép dữ liệu có thể được ghi vào file. 
Trường hợp, mở file ở chế độ nhập vào, tức là cho phép dữ liệu được đọc vào từ file.
datafile.open("info.txt", ios::in); 
Các chế độ mở têp tin <FILE>

ios :: in                            Mở một tệp tin để đọc
ios :: out                          Mở một tệp tin có sẵn để ghi
ios :: app                         Mở một tệp tin có sẵn để thêm dữ liệu vào cuối tệp.
ios :: ate                          Mở tệp tin và đặt con trỏ tệp tin vào cuối tệp.
ios :: trunc                       Nếu tệp tin đã có sẵn thì dữ liệu của nó sẽ bị mất.
ios :: nocreate                 Mở một tệp tin, tệp tin này bắt buộc phải tồn tại
ios :: noreplace               Chỉ mở têp tin khi tệp tin chưa tồn tại.
ios :: binary                     Mở một tệp tin ở chế độ nhị phân
ios :: text                         Mở một tệp tin ở chế độ văn bản.
Lưu ý:Bạn có thể mở tệp tin đồng thời 1 lúc ở nhiều chế độ.
1.1.1.Các phép xử lý vào/ ra trên file
a.Ghi tệp văn bản bằng:"<<"
Các bước ghi dữ liệu vào tệp tin như sau:
-       Mở file chỉ để đọc:
ofstream <Tên biến file> (<Tên file>, ios :: out);
Hoặc:
ofstream <Tên biến file> (<Tên file>); // Mặc định c++ sẽ tự thêm ios :: out
-       Ghi dữ liễu vào file thao tác: "<<"
<Tên biến file> << <Dữ liệu cần ghi>;
-       Đóng file
<Tên biến file>.close();
b. Đọc tệp văn bản bằng: ">>"
Các bước ghi dữ liệu vào file như:
-       Mở file chỉ để đọc:
ofstream <Tên biến file> (<Tên file>, ios :: in);
Hoặc:
ofstream <Tên biến file> (<Tên file>); // Mặc định c++ sẽ tự thêm ios :: in
-       Đọc dữ liễu vào file thao tác: "<<"
<Tên biến file> << <Dữ liệu cần đọc>;
-       Đóng tệp tin
<Tên biến file>.close();
Ví dụ 1:
#include <iostream> 
#include <fstream> 
using namespace std; 
int main() 

fstream dataFile; 

cout << "Thuc hien mo File...\n"; 
dataFile.open("demofile.txt", ios::out); // Mở file để ghi vào 
cout << "Du lieu duoc ghi xuong file.\n"; 
dataFile << "Mai Anh\n"; // Ghi dòng thứ 1 
dataFile << "Thuan Binh\n"; // Ghi dòng thứ 2 
dataFile << "An Dong \n"; // Ghi dòng thứ 3 
dataFile.close(); // Đóng file 
cout << "Xong.\n"; 
return 0; 
}
Output File
Mai Anh
Thuan Binh
An Dong
Quá trình đó thực sự như sau :
Mai Anh\nThuan Binh\nAn Dong\n<EOF>.
Khi file lại được mở ra thì dữ liệu mới lại được gắn vào chỗ end-of-file đó.
Ví dụ 2: Định dạng file xuất ra
#include <iostream> 
#include <iomanip> 
#include <fstream> 
using namespace std; 

int main() 

fstream dataFile; 
double num = 17.816392; 
dataFile.open("numfile.txt", ios::out); 
dataFile << fixed; // Định dạng fixed-point 
dataFile << num << endl; //Xuất ra num 
dataFile << setprecision(4); // Định dạng 4 phần thập phân sau dấu . 
dataFile << num << endl; //Xuất ra num 
dataFile << setprecision(3); // Định dạng 3 phần thập phân sau dấu . 
dataFile << num << endl; // Xuất ra num 
dataFile << setprecision(2); // 2 phần 
dataFile << num << endl; // xuất ra 
dataFile << setprecision(1); // 1 phần 
dataFile << num << endl; // xuất ra 
dataFile.close(); // Đóng file 
return 0; 
}
Output
17.816392
17.8164
17.816
17.82
17.8
1.1.2.Kiểm tra sự tồn tại của File trước khi mở hoặc mở file không được
Đôi khi chúng ta sẽ cần quyết định xem file có tồn tại trước khi chúng ta mở nó ra hay không và sau đây là 1 ví dụ:
fstream dataFile; 
dataFile.open("input.txt", ios::in); 
if(dataFile.fail()) 

//Nếu file không tồn tại, thì tạo ra 1 file mới 
dataFile.open("input.txt", ios::out); 
//... 

else 

dataFile.close(); 
2.1. Đối với file nhị phân
2.2.1.Định nghĩa :
File nhị phân là file chứa nội dung không nhất thiết phải là ASCII text.
Xét ví dụ sau :
ofstream file("num.dat"); 
short x = 1297; 
file << x; 
Dòng lệnh cuối cùng của ví dụ trên sẽ ghi nội dung của x vào file. Và chúng được lưu vào ở dạng kí tự '1', '2', '9', '7'.
Thực sự là con số 1297 không hề được lưu trong bộ nhớ. Nó đã được định dạng thành 1 số nhị phân, và chiếm 2 byte trong bộ nhớ máy tính.
Vì x kiểu short nó sẽ được lưu như sau :
00000101 | 00010001
Và đây chính là dữ liệu nguyên thuỷ được lưu trong bộ nhớ. Để làm được như vậy chúng ta sẽ có cú pháp như sau :
 file.open("stuff.dat", ios::out | ios::binary); 
2.2.2.Vào/ ra trên file nhị phân
Vào ra tệp tin nhị phân bằng: read và write
a.Write
-Hàm write dùng để ghi 1 file stream ở định dạng nhị nhận. Dạng tổng quát của hàm write như sau :
fileObject.write(address, size); 
Lưu ý :

-fileObject là tên của đối tượng file stream.
-address là địa chỉ đầu tiên của 1 vùng nhớ được ghi vào file. Đối số này có thể là địa chỉ của 1 kí tự hoặc là con trỏ tới kiểu char.
-size là số lượng byte của vùng nhớ mà nó được write. Đối số này bắt buộc phải là kiểu integer( số nguyên dương )
Ví dụ :
char letter = 'A'; 
file.write(&letter, sizeof(letter));
-Đối thứ nhất ở đây là địa chỉ của biến letter. Và đối này sẽ nói cho hàm write biết rằng dữ liệu được ghi vào file ở đâu trong vùng nhớ. 
-Đối thứ 2 sẽ là kíck thước của biến letter, và đối này sẽ nói cho hàm write biết số lượng byte của dữ liệu sẽ ghi vào file. Bởi vì dữ sẽ được lưu khác nhau trên tuỳ hệ thống khác nhau, nên cách tốt nhất là chúng ta dùng toán tử sizeof để quyết định số bytes được ghi. Và sau khi hàm này được thực hiện, nội dung của biến letter sẽ được khi vào file nhị phân của đối tượng "file"đó.

Chúng ta xem tiếp 1 ví dụ khác
 
char data[] = {'A', 'B', 'C', 'D'}; 
file.write(data, sizeof(data)); 
Trong ví dụ này thì đối thứ 1 là tên của mãng (data). Vì khi ta truyền tham số là tên của mãng thì tức là ta đã truyền con trỏ trỏ tới vị trí đầu tiên của mãng. Đối thứ 2 cũng có ý nghĩa tượng tự như ví dụ 1. Và sau khi gặp này thực hiện thì nội dung của mãng sẽ được ghi vào file nhị phân tương ứng với đối tượng file.
b.Read:
Hàm read thì sẽ dùng đọc vào số dữ liệu nhị phân từ file vào bộ nhớ máy tính. Dạng tổng quát là :
        fileObject.read(address, size);
-Ở đây fileObject là tên của đối tượng file stream.
-address là địa chỉ đầu tiên mà vùng nhớ mà dữ liệu được đọc vào được lưu. Và đối này có thể là địa chỉ của 1 kí tự hay 1 con trỏ tới kiểu char.
-size cũng là số lượng byte trong bộ nhớ được đọc vào từ file. Và đối này bắt buộc cũng phải là số kiểu integer ( nguyên dương )
Ví dụ :
char letter; 
file.read(&letter, sizeof(letter)); 
Hoặc :
char data[4];
file.read(data, sizeof(data)); 
Chương trình sau sẽ minh hoạ cách sử dụng 2 hàm read and write :
// Ghi các nội dung của mảng vào tập tin.
cout << "Viết các ký tự để các tập tin. \ n";
file.write (dữ liệu, sizeof (dữ liệu));

// Đóng tệp.
file.close ();

// Mở file cho đầu vào trong chế độ nhị phân.
file.open ("test.dat", ios :: in | ios :: binary);

// Đọc nội dung của tập tin vào mảng.
cout << "Bây giờ đọc lại dữ liệu vào bộ nhớ. \ n";
file.read (dữ liệu, sizeof (dữ liệu));

// Hiển thị nội dung của mảng.
for (int count = 0; count <SIZE; đếm ++)
cout << dữ liệu [count] << "";
cout << endl;

// Đóng tệp.
file.close ();
return 0;
}
Nếu chúng ta muốn ghi các kiểu khác vào file nhị phân thì ta phải dùng cú pháp có 1 tí đặt biệt sau đây.
reinterpret_cast<dataType>(value)
Ở cú pháp trên thì dataType sẽ là kiểu dữ liệu mà chúng ta muốn ép về, và value sẽ là giá trị mà chúng ta muốn ép.
Ví dụ :
int x = 65; 
file.write(reinterpret_cast<char *>(&x), sizeof(x)); 
Đối với mảng thì :
const int SIZE = 10; 
int numbers[SIZE] = {1,2,3,4,5,6,7,8,9,10}; 
file.write(reinterpret_cast<charr *>(numbers), sizeof(numbers)); 
Ví dụ :
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
const int SIZE = 10;
fstream file;
int numbers[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// Open the file for output in binary mode.
file.open("numbers.dat", ios::out | ios::binary);

// Write the contents of the array to the file.
cout << "Writing the data to the file.\n";
file.write(reinterpret_cast<char *>(numbers), sizeof(numbers));

// Close the file.
file.close();

// Open the file for input in binary mode.
file.open("numbers.dat", ios::in | ios::binary);

// Read the contents of the file into the array.
cout << "Now reading the data back into memory.\n";
file.read(reinterpret_cast<char *>(numbers), sizeof(numbers));

// Display the contents of the array.
for (int count = 0; count < SIZE; count++)
cout << numbers[count] << " ";
cout << endl;

// Close the file.
file.close();
return 0;
}

Con trỏ vị trí File trong C++

Cả hai đối tượng istream và ostream đều cung cấp các hàm thành viên để xác định lại vị trí của con trỏ vị trí file (file-position pointer). Các hàm thành viên này là seekg (viết tắt của seek get) cho istream và seekp (viết tắt của seek put) cho ostream trong C++.
Tham số cho seekg và seekp thương là một long int. Tham số thứ hai có thể được xác định để chỉ dẫn hướng tìm kiếm. Hướng tìm kiếm có thể là ios::beg (mặc định) để xác định vị trí liên quan tới phần bắt đầu của một Stream, là ios::cur để xác định vị trí liên quan tới vị trí hiện tại trong một Stream hoặc là ios::end để xác định vị trí liên quan tới phần kết thúc của một Stream trong C++.
Con trỏ vị trí file là một giá trị integer mà xác định vị trí trong file, tính toán là số byte từ vị trí bắt đầu của file đó. Dưới đây là một số ví dụ để xác định vị trí của con trỏ vị trí file trong C++:
// xac dinh vi tri byte thu n cua doi tuong file
doi_tuong_file.seekg( n );

// xac dinh vi tri n byte ve sau cua doi tuong file
doi_tuong_file.seekg( n, ios::cur );

// xac dinh vi tri n byte bat dau tu cuoi cua doi tuong file
doi_tuong_file.seekg( n, ios::end );

// xac dinh vi tri tai cuoi doi tuong file
doi_tuong_file.seekg( 0, ios::end );

Nhận xét

Bài đăng phổ biến từ blog này

Entry Test của FPT

IQ - Kiểm tra tư duy logic (8/20) - GMAT- Kiểm tra khả năng tính toán trong thời gian ngắn (8/20) - Tiếng Anh (18-> 25/50) - Các bài thi chuyên môn - FE (8/20) IQ: lên mạng tìm "IQ test" là ra đầy. + GMAT: Những câu trắc nghiệm tính toán đơn giản kiểu như sau:  1 . Một shop thời trang sale off quần jeans 15 %, quần jeans giá 450 $, người mua đưa 500 $, hỏi cashier trả lại bao nhiêu $ tiền thừa.? 2 . 100 % là 180 , vậy 150 là bao nhiêu %? Tiếng anh: Cỡ như thi TOEIC thôi. Chuyên môn: Mobile thì trắc nghiệm Java. Qúa trình tuyển như sau :v Lần 1: Test IQ, Tiếng Anh( mình làm í ẹ khoảng 50% mà vẫn được) , Java Lân 2: được gọi điện lên :)) + Gioi thiệu bản thân + Họ chỉ hỏi các câu căn bản như: -. OOP: là gì, 4 tính chất, ví dụ, khác nhau giữa interface và abstract - CODE: hầu toàn các bài toán vòng for :)) , cẩn thận mấy câu kế thừa. SQL (distinct, view, function, cursor, store procedure, ...v.v.), nhớ có câu cộng 2 số int không dùng biến đệm hơi khoai haha + Nói ch...

Java: Java Package-Thư viện trong Java

Giới thiệu về Package Các bạn mới học lập trình Java thường không dể ý tới package vì các bạn toàn tạo file .java vào cùng 1 chỗ, không cần sắp xếp, không cần quản lý truy nhập. Nhưng để tăng kỹ năng lập trình với Java, các bạn cần phải tìm hiểu về package trong Java. Các bạn có thể tham khảo định nghĩa sau: Package được dùng để đóng gói các lớp trong chương trình lại với nhau thành một khối. Đây là cách tốt nhất để lưu trữ các lớp gần giống nhau hoặc có cùng một module thành một khối thống nhất – để đáp ứng 1 khối chức năng. Từ đây mình sẽ giới thiệu thêm với các bạn các câu lệnh nhâp khẩu,nó có định dạng như sau : Định dạng :  import javaPackageNameImport;    Nó giống như khai báo thư viện ở các ngôn ngữ lập trình khác.Như vậy,chỉ khi các bạn nhập khẩu chúng,các bạn mới có thể sử dụng thư viện mà chúng cung cấp cho ta. VD :    import java.util.Date;   import java.text.SimpleDateFormat; Lưu ý : -Các câu lệnh nhập khẩu rất nhiều và...

Khác nhau giữa Array và ArrayList và HashMap

Collection bản chất là tập các lớp dùng để lưu trữ danh sách và có khả năng tự co giãn khi danh sách thay đổi : Thêm , sửa , xóa , chèn … Hai lớp Collection thường được sử dụng nhiều nhất là ArrayList và Hashmap Giới thiệu về ArrayList ArrayList sử dụng cấu trúc mảng để lưu trữ phần tử , tuy nhiên có hai đặc điểm khác mảng : Không cần khai báo trước kiểu phần tử . Không cần xác định trước số lượng phần tử ( kích thước mảng ). N ó có kh ả năng truy c ậ p ph ầ n t ử ng ẫ u nhiên (Do th ừ a k ế t ừ interface RandomAccess ). P hương thức khởi tạo ● ArrayList () ● ArrayList (Collection c) ● ArrayList ( int initialCapactity ) Các phương thức chính ● add(Object o) ● remove(Object o) ● get( int index) ● size() ● isEmpty () ● contains(Object o) ● clear() Giới thiệu về HashMap ● Là ki ể u t ậ p h ợ p t ừ đ i ể n, HashMap cho phép truy xu ấ t tr ự c ti ế p t ớ i m ộ ...