PDA

View Full Version : All about File I/O in C++ (part II)



cuonguyen
27-09-2002, 09:53
3. Quản lý Iuồng I/O.

Trong phần này chúng ta sẽ học về một số hàm hữu dụng.
Phần trước chúng ta đã tạo một file bằng lệnh:

ofstream File(“filename.txt”);

Chúng ta có một cách khác đó là sử dụng hàm open():

ofstream File;
File.open(“finename.txt”);

Hàm open() nguyên dạng:

void open(char *filename, [int open_mode]);

trong đó tham số open_mode chỉ ra phương thức mở file. Nó có thể có các giá trị sau:

+ ios::in -> mở file để đọc.
+ ios::out -> mở file để ghi.
+ ios::app -> mở file để ghi vào cuối file. Nó gọi ios::out (?).
+ ios::ate -> mở file để ghi vào cuối. Nó không gọi ios::out (?).
+ ios::trunc -> xoá tất cả nội dung đã có.
+ ios::nocreate -> nếu file chưa tồn tại, sẽ không mở được.
+ ios::noreplace -> nếu file đã tồn tại, cố gắng mở sẽ gây lỗi.
+ios::binary -> mở file binary.

Ví dụ 1:

#include <fstream.h>
void main()
{
ofstream WriteToFile(“first.txt”, ios::ate);
WriteToFile<<”\nI love you”;
WriteToFile.close();
}
Kết quả là file “first.txt” (phần trước) có nội dung là:

Hello World!
I love you

Nếu không có tham số ios::ate thì nội dung của file lúc trước sẽ bị xóa.

Ví dụ 2: Nếu chưa có file “non_exit.txt”.
#include <fstream.h>
void main()
{
ofstream File(“non_exit.txt”, ios::nocreate);
if(!File) {
cout<<”Error openning.”;
exit(1);
}
File.close();
}

Kết quả: “Error openning.” và không tạo file trong thư mục của bạn. Nếu không có tham số ios::nocreate thì vẫn vô tư, nghĩa là không có dòng thông báo lỗi và vẫn tạo ra file “non_exit.txt”.

Ví dụ 3:
#include<fstream.h>
int main()
{
ifstream File(“first.txt”, ios::noreplace);
if(!File) {
cout<<”Error!”;
exit(1);
}
File.close();
return 0;
}

Kết quả: “Error!”, vì file “first.txt” đã tồn tại. Tham số ios::noreplace không cho phép mở file đã tồn tại.
Nếu bạn muốn có nhiều phương thức mở bạn dùng toán tử OR (|):

ios::ate | ios::binary

Sử dụng open_mode, chúng ta có thể vừa mở file để đọc và để ghi. Ví dụ:

#include <fstream.h>

void main()
{
fstream File("second.txt",ios::in | ios::out);
File << "Hi! I’m there.";
char ch;
File.seekg(ios::beg);
while(!File.eof())
{
File.get(ch);
cout <<ch;
}
cout<<endl;
File.close();
}

Có cái gì mới mẻ ở đây ấy nhỉ. Okay, chúng ta sẽ hiểu ngay thôi.

fstream File(“test.txt”, ios::in | ios::out); - vì mở file vừa để đọc và ghi nên chúng ta tạo một đối tượng thuộc lớp fstream (chứ không phải ofstream-để ghi hay ifstream để đọc).

File.seekg(ios::beg); - A đây rồi, cái này có vẻ hơi mới mẻ nhỉ (tất nhiên là với người bắt đầu học). Để xem tại sao lại phải sử dụng “nó” chúng ta hãy xem khối lệnh:
while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}
Khối lệnh này chắc hẳn bạn đã biết. Hàm get(ch) sẽ đọc một kí tự của file và gán cho biến ch. Vòng lặp sẽ kết thúc khi đến cuối file. Để vòng lặp “biết” được khi nào thì kết thúc file thì, khi đọc file có một “con trỏ trong” (inside-pointer). Sau khi get(ch) thực hiện việc gán cho ch kí tự hiện hành thì “inside-pointer” sẽ chỉ đến kí tự tiếp theo. Cứ thế, đến lần lặp sau ch sẽ nhận được giá trị tiếp theo cho đến khi kết thúc file.

Quay trở lại hàm seekg(). Lý do phải sử dụng hàm này vì sau câu lệnh:

File<<”Hi! I’m there”;
thì “inside-pointer” sẽ trỏ đến cuối file. Vì vậy phải dùng câu lệnh:

File.seekg(ios::beg);

để đưa “inside-pointer” về đầu file. Bạn có thể sử dụng các tham số cho hàm seekg() như sau:
ios::beg – đưa “inside-pointer” về đầu file (có giá trị là 0).
ios::end - đưa “inside-pointer” về cuối file. Nhưng tại sao tôi thấy tham số này luôn chỉ đến kí tự thứ 3 thế nhỉ (giá trị 2)?
Hoặc bạn có thể dùng:

File.seekg(4); -> “inside-pointer” chỉ đến kí tự thứ 4 kể từ đầu file (ký tự đầu là 0).
File.seekg(-5,ios::end); -> đưa “inside-pointer” đến cuối file sau đó quay lại 5 kí tự.

Ví dụ:
#include<fstream.h>
main()
{
ifstream File(“second.txt”);
char ch;
File.seekg(-5, ios:end);
File.get(ch);
cout<<ch;
File.close();
}

Nội dung file “second.txt” là “Hi! I’m there.”
Kết quả được “h”.
Như trên đã nói, ngoài cách đọc từng char, ta có thể đọc từng word, hay từng line.
Ví dụ:
#include<fstream.h>
void main
{
ifstream File(“first.txt”, ios::in);
char str[30];//lưu trữ từng từ vào str.
while(!File.eof())
{
File >> str;
cout << str<<” “;
}
File.close();
}

File>>str sẽ đọc từng từ và gán cho str. Kết quả ta sẽ được “Hello World! I love you.” (không xuống dòng-đây là nhược điểm của phương pháp này).

Bạn có thể đọc từng line. Ví dụ:
#include<fstream.h>
void main()
{
ifstream File(“first.txt”);
char line[100]; //lưu trữ toàn bộ dòng vào biến này
while(!File.eof())
{
File.getline(line,100);
cout << line << endl;
}
File.close();
}

Kết quả:
Hello World!
I love you.

Như vậy, một điều khuyên cho các bạn đó là sử dụng cách đọc từng char, hoặc từng line. Vậy ta có thể đọc file theo 3 cách:
- Đọc từng char: File.get(ch);
- Đọc từng word: File>>ch;
- Đọc từng line: File.getline(ch,dimension);

(còn tiếp)

cuonguyen
27-09-2002, 10:01
Hic ":o" biến thành :o hết rùi.

Old Shark
30-09-2002, 11:05
lol lol lol Tại bạn quên tắt smile lol lol lol

pmlove760189
01-11-2009, 15:29
Cho e hỏi part 1 ở đâu vậy?