Bài giảng môn Lập trình hướng đối tượng - Chương 6: Dòng nhập xuất (IO-stream)

pdf 25 trang phuongnguyen 5460
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng môn Lập trình hướng đối tượng - Chương 6: Dòng nhập xuất (IO-stream)", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_mon_lap_trinh_huong_doi_tuong_chuong_6_dong_nhap_x.pdf

Nội dung text: Bài giảng môn Lập trình hướng đối tượng - Chương 6: Dòng nhập xuất (IO-stream)

  1. Ch ươ ng 6: Dịng nh p xu t (IO-stream) 6.1. Dn nh p • Ta cĩ th gi hàm printf() vi đ nh d ng “ %d ” đ in ra màn hình m t s nguyên (int ), đnh d ng “ %f ” đ in ra màn hình s th c ( double ), v.v Hàm printf() cĩ th in ra màn hình giá tr c a mt đ i t ưng thu c l p CComplex khơng? • ðon ch ươ ng trình sau cĩ ho t đ ng khơng? #include "Complex.h" #include using namespace std; int main( ) { CComplex c(5, 6); cout << c; return 0; } • Làm th nào đ đon ch ươ ng trình trên làm vi c đưc? 6.2. Gi i thi u • C cung c p m t th ư vi n các hàm nh p xu t khá m nh nh ư printf , scanf , puts , fwrite , v.v ( đưc khai báo trong file stdio.h ). Tuy nhiên các hàm này cĩ 2 nh ưc đim sau: o Khơng th dùng đưc v i các ki u d li u do ng ưi l p trình t đnh ngh ĩa (ví d nh ư l p CComplex ). o Khơng nh t quán v th t và ng ngh ĩa c a các tham s . • ð kh c ph c các nh ưc đim trên, th ư vi n chu n c a C++ đư a ra mt tp các lp ph c v riêng cho vi c xu t nh p. Các l p này đưc g i là th ư vi n các dịng nh p xu t (io-stream library ) hay th ư vi n dịng (stream library ). S d ĩ ta g i th ư vi n này nh ư th vì nĩ đưc xây d ng d a trên mt khái ni m cĩ tên dịng (stream ). Ng ưi l p trình cĩ th m r ng các l p thu c th ư vi n dịng đ nh p/xu t đưc các ki u d li u do h t đ nh ngh ĩa và ph c v cho nh ng mc đích riêng c a h . 6.3. Khái ni m v dịng (stream) • Stream là khái ni m trung tâm ca th ư vi n dịng, t đĩ xây d ng lên các l p ph c v cho vi c nh p xu t (tm g i là các iostream class ). Ta hình dung stream gi ng nh ư m t tp tin đc bi t, ta cĩ th đ c d li u t nĩ ho c vi t d li u lên nĩ. Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 1
  2. • Trong th ư vi n dịng , m i lo i dịng (stream ) đưc gn li n v i (tr u t ưng hố thành) mt l p. ð c tính c a mt lo i stream đưc xác đ nh b i l p g n li n v i nĩ và các tốn t (chèn, tách, v.v ), các ph ươ ng th c c a l p đĩ. Mt dịng là mt đ i t ưng c a l p g n li n v i lo i dịng đĩ. • Thơng qua các device drivers , h điu hành (c th là th ng qu n lý file – file system ) làm vi c v i bàn phím, màn hình, máy in, và các c ng giao ti p nh ư là các file m r ng đc bi t (extended files ). Các iostream classes cĩ th t ươ ng tác vi các file đ c bi t này. Nh ư v y thơng qua các iostream classes , ng ưi l p trình cĩ th t ươ ng tác vi màn hình, bàn phím, các c ng giao ti p v.v gi ng nh ư tươ ng tác v i các file trên đĩa. • Các iostream classes cũng h tr vi c đ c và vi t vào b nh vi cú pháp gi ng nh ư th c hi n các thao tác truy xu t đĩ a (disk I/O). 6.4. Dịng xu t (output stream) • Dịng xu t là n ơi ch ươ ng trình cĩ th xu t d li u ra đĩ, là đích đn c a các bytes d li u trong các thao tác xu t. • Ba lo i dịng xu t (output stream classes ) quan tr ng nh t trong th ư vi n dịng là: o ostream o ofstream o ostrstream • Trong th ư vi n dịng, ng ưi ta khai báo sn 6 bi n ( đ i t ưng, dịng) tồn cc thu c lp dịng xu t ostream . Các bi n này đưc khai báo trong file . o cout: dịng xu t chu n (standard output) dùng cho các ký t 1 byte (ANSI), cĩ buffering. o wcout: dịng xu t chu n dùng đ xu t các ký t Unicode (wide character ). o cerr: dịng li chu n, khơng buffering khi chèn (unbuffered insertions ). o werr: tươ ng t cerr nh ưng dùng cho wide character . o clog tươ ng t cerr nh ưng cĩ buffering khi th c hi n chèn. o wclog : t ươ ng t clog nh ưng dùng cho wide character . o Ví d : #include #include using namespace std; void TestWide( ) { int i = 0; wcout > i; wcerr << L "test for wcerr" << endl; wclog << L "test for wclog" << endl; } Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 2
  3. int main( ) { int i = 0; cout > i; cerr << "test for cerr" << endl; clog << "test for clog" << endl; TestWide( ); return 0; } Xu t ra màn hình: Enter a number: 3 test for cerr test for clog Enter a number: 1 test for wcerr test for wclog • Lp ostream : o Cĩ th đưc dùng cho các thao tác buffered ho c unbuffered o Th ưng đưc dùng đ xu t mt dãy các byte trong ch đ v ăn b n. o Khi kh i t o m t đ i t ưng thu c l p ostream , ta ph i cung c p m t đ i tưng thu c l p streambuf cho constructor ca nĩ. o ostream đưc k t th a t l p ios . • Lp ofstream : o Lp ofstream h tr vi c xu t d li u ra file trên đĩa. o Khi cĩ nhu c u ch xu t d li u ra đĩ a (khơng đc d li u t đĩ a), ta nên dùng m t đ i t ưng thu c l p ofstream . o Ta cĩ th ch đ nh đi t ưng ofstream làm vi c ch đ text hay ch đ nh phân tr ưc ho c sau khi m m t file g n v i đ i t ưng thu c l p ofstream . o Nu ta ch đ nh tên file trong constructor, file đĩ s t đ ng đưc m khi đi t ưng đưc kh i t o. Ta c ũng cĩ th dùng ph ươ ng th c open đ m mt file sau khi đã kh i t o đ i t ưng bng constructor mc đ nh. • Lp ostrstream : o Tươ n t hàm sprintf() trong th ư vi n C - run time , lp ostrstream h tr vi c xu t d li u vào m t chu i trong b nh (in-memory strings ). o ð t o m t chu i trong b nh bng cách dùng stream, ta kh i t o m t đ i tưng thu c l p ostrstream . o Vì các đi t ưng thu c l p ostrstream là “ write-only ”, nên ch ươ ng trình ch cĩ th truy xu t chu i k t q a thơng qu mt con tr tr t i char . 6.4.1. Kh i t o các dịng xu t (output stream objects) • Ta th ưng dùng các đi t ưng đã đnh ngh ĩa tr ưc nh ư cout , cerr , ho c clog . Khi dùng các dịng xu t này, ta khơng c n ph i kh i t o l i thơng qua constructor ca lp ostream . • Ta ph i s d ng constructors đ kh i t o các dịng xu t trong 2 tr ưng h p sau: Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 3
  4. o Kh i t o dịng xu t ra file. o Kh i t o dịng xu t ra m t in-memory string . 6.4.1.1. Kh i t o dịng xu t ra file (ofstream object) • Ta cĩ th kh i t o m t dịng xu t ra file (output file stream ) theo m t trong 2 cách sau: o Dùng constructor mc đ nh, sau đĩ g i ph ươ ng th c open() . ofstream myFile; // Static or on the stack myFile.open( "C:\\test.txt" ); // HO C ofstream* pmyFile = new ofstream; // On the heap pmyFile->open( "C:\\test.txt" ); o Xác đnh tên file và ch đ m trong constructor: ofstream myFile( "C:\\test.txt", ios_base::out); 6.4.1.2. Kh i t o dịng xu t ra in-memory string (ostrstream object) • Ta s d ng m t trong hai cách sau. Khi kh i t o, ta c n dùng manipulator ends đ thêm ký t k t th c chu i null vào chu i (manipulator là các ph n t đưc dùng đ thay đ i đ nh d ng c a d li u trong các stream). o Kh i t o đ ng, dịng xu t t c p phát vùng nh : char * sp; ostrstream myString; mystring << "this is a test" << ends; sp = myString.str(); // Get a pointer to the string o Kh i t o t ĩnh. ðịi h i mt vùng nh đưc c p phát tr ưc: char s[32]; ostrstream myString( s, sizeof ( s ) ); myString << "this is a test" << ends; // Text is stored in s 6.4.2. Dùng tốn t chèn và ph ư ng th c điu khi n đnh d ng • Ph n này đ c p v cách điu khi n vi c đ nh d ng và cách overload tốn t chèn đ cĩ th làm vi c đưc v i các ki u d li u do ng ưi l p trình t đ nh ngh ĩa. • Theo m c đ nh tốn t chèn ( << ), cĩ th đưc s d ng cho t t các các ki u d li u chu n c a C++, nĩ g i các bytes ti m t dịng xu t b t k ỳ (output stream object). ð tốn t chèn cĩ th làm vi c đưc v i các ki u d li u do ng ưi l p trình đnh ngh ĩa, ta ph i đnh ngh ĩa ch ng (overload) tốn t chèn. • Ta th ưng s d ng ph i h p tốn t chèn cùng v i các b ph n đ nh d ng (manipulators). • ð điu khi n đ nh d ng, ta tác đng vào các tu ỳ ch n sau: Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 4
  5. o Output width o Alignment o Precision o Radix 6.4.2.1. Output width (đ r ng c a output) • ð canh l output, ta ch đ nh chi u r ng c a output cho tng d li u xu t (mc xu t, tr ưng ) bng m t trong hai cách: o Dùng manipulator setw (ph i #include ) đ ch đ nh chi u r ng ca t ng thành ph n d li u trên cùng m t dịng. Trong ví d d ưi đây, các chu i đưc in trong tr ưng cĩ chi u r ng 6, các s đưc in trong tr ưng cĩ chi u rng 7: #include #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; char *names[] = { "Zoot" , "Jimmy" , "Al" , "12Stan" }; for ( int i = 0; i using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; for ( int i = 0; i < 4; i++ ) { cout.width(10); cout << values[i] << '\n' ; } return 0; Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 5
  6. } Output 1.23 35.36 653.7 4358.24 • C setw và width() đu khơng c t b các giá tr trong tr ưng h p giá tr cĩ s ký t l n h ơn chi u r ng. N u output cĩ s ký t v ưt qúa chi u r ng, tồn b giá tr ca output s đưc in (s ký t đưc in do precision ca stream quy t đ nh). • C setw và width() ch tác đ ng đ n tr ưng theo ngay sau nĩ. • Ngay sau khi output đưc in, tùy ch n width s đưc ph c h i v giá tr m c đ nh (bng 0). Ta nĩi tùy ch n width cĩ nh h ưng nh t th i. • Ngồi width , tt c các tu ỳ ch n đ nh d ng stream (stream format options ) gi nguyên nh h ưng cho đ n khi ta đ t l i giá tr m i cho chúng. Ta nĩi nh ng tùy ch n này cĩ nh h ưng lâu dài . • ð chèn ký t vào ch tr ng trong m t tr ưng cĩ s ký t nh h ơn chi u r ng, ta dùng ph ươ ng th c fill() . Ký t m c đ nh đưc chèn là ký t tr ng (blank). Ví d : #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; for ( int i = 0; i < 4; i++ ) { cout.width( 10 ); cout.fill( '*' ); //using endl manipulator instead of '\n' character. cout << values[i] << endl; } return 0; } Output: 1.23 35.36 653.7 4358.24 Câu h i: • Trong ch ươ ng trình trên, n u ta đưa dịng l nh cout.fill( '*' ); lên tr ưc vịng for nh ư sau thì: a) Ch ươ ng trình s cho cùng k t q a nh ư trên b) Ch ươ ng trình s cho k t q a khác Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 6
  7. #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; cout.fill( '*' ); for ( int i = 0; i #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; char *names[] = { "Zoot" , "Jimmy" , "Al" , "Stan12" }; for ( int i = 0; i < 4; i++ ) cout << setiosflags( ios::left ) << setw( 6 ) << names[i] << resetiosflags( ios::left ) << setw( 7 ) << values[i] << endl; return 0; } Output: Zoot 1.23 Jimmy 35.36 Al 653.7 Stan124358.24 • Nh n xét: o Ta b t c left-align bng cách dùng manipulator setiosflags vi enumerator ios::left . o Enumerator ios::left đưc đ nh ngh ĩa trong l p ios , vì v y ta ph i dùng ti n t ios:: . o Manipulator resetiosflags(ios::left) s t t c left-align . o Khơng gi ng width() và setw , nh h ưng c a setiosflags và resetiosflags là lâu dài (s gi nguyên cho đn khi ta thay đ i). Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 7
  8. 6.4.2.3. Precision (đ chính xác) • ð chính xác m c đ nh đưc dùng cho các ki u d li u ch m đ ng (floating- point) là 6. Ví d , s 3466.9768 s đưc in là 3466.98 (g m 6 ch s cĩ ngh ĩa). • ð thay đ i đ chính xác, ta dùng cĩ th dùng: o Manipulator setprecision . o Ho c ph ươ ng th c precision() . • Manipulator setprecision cĩ 2 c : ios::fixed và ios::scientific . o Nu ios::fixed ho c ios::scientific đưc b t, giá tr c a precision s xác đnh s ch s xu t hi n sau d u ch m (ph n th p phân). o Nu c 2 c đ u khơng đưc b t, giá tr c a precision s xác đ nh t ng ch s cĩ ngh ĩa c a output. o Ví d :  Nu c ios::fixed đưc b t, s 3466.9768 s đưc in là 3466.976800 (6 ch s ph n th p phân).  Nu c ios::scientific đưc b t, s 3466.9768 s đưc in là 3.466977e+003 (6 ch s ph n th p phân). o Ta dùng manipulator resetiosflags đ xố 2 c này. o Theo m c đ nh, c c ios::fixed và ios::scientific đu khơng b t. • Các ví d : o Ví d 1: #include using namespace std; int main() { float pi = 3.1415927; int nOriPre = cout.precision(3); cout #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; char *names[] = { "Zoot" , "Jimmy" , "Al" , "Stan12" }; cout.fill( '*' ); for ( int i = 0; i < 4; i++ ) cout << setiosflags( ios::left ) << setw( 6 ) << names[i] << resetiosflags( ios::left ) << setw( 10 ) Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 8
  9. #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; char *names[] = { "Zoot" , "Jimmy" , "Al" , "Stan12" }; cout.fill( '*' ); cout #include using namespace std; int main( ) { double values[] = { 1.23, 35.36, 653.7, 4358.24 }; char *names[] = { "Zoot" , "Jimmy" , "Al" , "Stan12" }; cout.fill( '*' ); Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 9
  10. cout int main( void ) { using namespace std; double i = 1.23e100; // Scientific format cout << i << endl; cout << uppercase << i << endl; int j = 10; cout << hex << nouppercase << j << endl; cout << hex << uppercase << j << endl; return 0; } Output: 1.23e+100 1.23E+100 a A Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 10
  11. 6.4.3. Các ph ư ng th c c a dịng xu t ra file (output file stream) • Các ph ươ ng th c c a dịng xu t ra file g m 3 lo i: o Các ph ươ ng th c t ươ ng đươ ng v i manipulator s, o Các ph ươ ng th c th c hi n thao tác vi t khơng đ nh d ng, o Các ph ươ ng th c cịn l i dùng đ thay đi tr ng thái c a stream (khơng cĩ manipulator ho c tốn t chèn nào cĩ ch c n ăng t ươ ng t ). • ð xu t ra đĩa các d li u cĩ đ nh d ng và truy xu t tu n t (sequential, formatted output - text), ta ch c n dùng các tốn t chèn (insertion operators) và các manipulators là đ. • ð xu t ra đĩ a các d li u nh phân đưc truy xu t ng u nhiên, ta ph i dùng các ph ươ ng th c khác (cĩ th dùng kèm v i tốn t chèn). 6.4.3.1. Ph ươ ng th c open() • ð dùng m t dịng xu t ra file (đi t ưng thu c l p ofstream ), ta ph i gn v i dịng đĩ mt file bng 1 trong 2 cách (trong c 2 tr ưng h p, đi s mơ t file là gi ng nhau): o Dùng constructor. o Dùng ph ươ ng th c open() . • Khi dùng ph ươ ng th c open() đ g n m t file vi m t dịng xu t ra file (đi tưng thu c l p ofstream ), ta c n chú ý ch đ nh ch đ m file ( open mode ). Ch đ m file th ưng đưc g i là mode options hay các open flag . • Ta cĩ th k t h p nhi u open flag cùng lúc (các c này là các enumerators đưc khai báo trong l p ios ), bng cách dùng tốn t OR ( | ). • Các c này g m: o app : ðư a con tr chèn đn cu i dịng (t c cu i file g n li n v i dịng) tr ưc m i thao tác chèn.  Nu file ch ưa t n t i thì t o file m i.  Nu file đã t n t i ri thì mi file, sau đĩ đư a con tr chèn đn cu i dịng (cu i file). o ate : ðư a con tr đ n cu i dịng ngay sau khi dịng đưc kh i t o.  M m t file đã t n t i r i. Nu file ch ưa t n t i thì khơng to file mi.  Ngay sau khi m , đư a con tr c a file đ n cu i file.  Cho phép chèn d li u vao dịng. o binary : ðc file ch đ nh phân. o in :  Cho phép l y d li u t dịng.  M đưc file đã t n t i r i. Nu file ch ưa t n t i thì khơng to file mi ( đươ ng nhiên!). o out :  Cho phép chèn d li u vào dịng.  Nu file ch ưa t n t i thì t o file m i. Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 11
  12.  Nu file đã t n t i r i thì xĩa n i dung c a file đang t n t i. o trunc:  Cho phép chèn d li u (m i) vào dịng.  M đưc file đã tn t i ri. Nu file ch ưa t n t i thì khơng to file mi.  Ngay sau khi m file xong thì xố h t n i dung c ũ ( đ chu n b chép d li u m i vào file). • ði v i các dịng xu t, c ios::out luơn đưc b t. • Stream ( đi tưng) g n v i file th ưng đưc g i là đi t ưng điu khi n (controlling object ) c a file. • Ví d: #include int main ( ) { using namespace std; fstream file; file.open( "rm.txt" , ios_base::out | ios_base::trunc ); file int main ( ) { using namespace std; ofstream ofile( "C:\\temp.txt" ); //Default is ios::out // Ho c dùng cách d ưi đây: //ofstream ofile( "C:\\temp.txt", ios::out ); ofile int main ( ) { using namespace std; ofstream ofile( "C:\\temp.txt" , ios::app ); ofile << "testing" ; return 0; Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 12
  13. } o M l n l ưt t ng file trên cùng m t dịng (stream). Ti m i th i đim stream ch g n v i ( điu khi n đưc) m t file. #include #include int main ( ) { using namespace std; fstream ofile; ofile.open( "C:\\temp1.txt" , ios::out | ios::trunc ); ofile >str1; ifile.close(); ifile.clear(); // Xĩa c l i. ifile.open( "C:\\temp2.txt" , ios::in ); string str2; ifile>>str2; ifile.close(); cout << str1 << endl; cout << str2 << endl; return 0; } Output: testing1 testing2 Câu h i: • Trong ch ươ ng trình trên, n u ta b dịng : ifile.clear(); // Xĩa c l i. thì ch ươ ng trình s : Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 13
  14. a) In ra màn hình: c) C 2 chu i testing1 và testing2 đu testing1 khơng đưc in ra màn hình. Khơng b) In ra màn hình: in thơng báo l i. testing1 d) Ch ương trình ch in m t câu thơng testing2 báo l i. 6.4.3.2. Ph ươ ng th c put() • Ph ươ ng th c put() vi t m t ký t ra dịng xu t. • Theo m c đ nh, 2 dịng sau đây là t ươ ng đươ ng. Tuy nhiên dịng th 2 ch u nh hưng c a các đ i s đ nh d ng dịng: cout.put( 'A' ); // Exactly one character written cout using namespace std; struct Date { int mo, da, yr; }; int main( ) { Date dt = { 6, 10, 92 }; ofstream tfile( "C:\\temp.dat" , ios::binary ); tfile.write( ( char *) &dt, sizeof (dt) ); return 0; } • Ph ươ ng th c write() khơng dng l i khi g p ký t k t thúc chu i (null character), vì v y tồn b structure đưc vi t h t ra stream. Ph ươ ng th c write() gm 2 đ i s: char* và s byte đưc vi t vào stream. Trong ví d trên, ta ph i ép đ a ch c a structure dt thành char* . 6.4.3.4. Ph ươ ng th c seekp() và tellp() • Dịng xu t ra file (output file stream) ch a m t bi n pos cho bi t v trí ti p theo s đưc vi t trong file. • Ph ươ ng th c seekp() cho phép đt giá tr m i cho bi n pos . • Ph ươ ng th c tellp() cho bi t giá tr hi n hành c a bi n pos . Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 14
  15. • Ví d : #include using namespace std; int main( ) { char cArray[18] = "Khoa CNTT, DHSPKT" ; fstream ofile( "C:\\temp1.txt" ); if ( ofile ) { for (int i = 0; i using namespace std; int main( ) { char cArray[18] = "Khoa CNTT, DHSPKT" ; fstream ofile( "C:\\temp1.txt" , ios::out|ios::trunc ); if ( ofile ) { Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 15
  16. for (int i = 0; i pos = 5; ofile.seekp(ofile.tellp() + pos); ofile << cArray[i]; } } else { cout<< "ERROR: Cannot open file 'temp1.txt'." <<endl; } return 0; } 6.4.3.5. Ph ươ ng th c close() • Ph ươ ng th c close() th c hi n vi c đĩng file gn li n v i output file stream. • File bt bu c ph i đưc đĩng đ hồn t t vi c xu t d li u ra output file stream. • Ph ươ ng th c close() , đưc g i trong destructor c a l p ofstream. • Ta ph i g i ph ươ ng th c close() tr ưc khi g i ph ươ ng open() đ m m t file khác gn li n v i cùng output file stream. • Destructor ca ofstream ch th c hi n vi c đĩng file mt cách t đ ng cho các file đưc m t đ ng b ng constructor c a l p ofstream ho c đưc m b ng ph ươ ng th c open() . Nu ta truy n vào constructor ca ofstream mt file descriptor ca m t file đã đưc m s n ho c dùng ph ươ ng th c attach() , ta ph i th c hi n vi c đĩng file mt cách t ưng minh tr ưc khi đ i tưng output file stream b hu b . 6.4.3.6. Các ph ươ ng th c x lý l i • Ta s d ng các ph ươ ng th c sau đ ki m tra l i trong khi xu t d li u ra m t dịng xu t ho c nh p d li u t dịng nh p: Ph ươ ng th c Giá tr tr v bad() Tr v true nu cĩ l i khơng th ph c h i đưc (unrecoverable error). fail() Tr v true nu cĩ unrecoverable error ho c các l i thơng th ưng nh ư khơng tìm th y file v.v . Vi c x lý cĩ th đưc ph c h i l i sau khi g i ph ươ ng th c clear() . good() Tr v true nu khơng cĩ b t k ỳ l i nào. eof() + Tr v true (bít l i eof đưc b t) nu đã đn k t thúc file. + N u ta dùng ph ươ ng th c seekp() ho c seekg() đ đưa con tr v tr ưc eof c a file thì bít l i eof t đ ng đưc t t (ph ươ ng th c eof() s tr v false ). clear() ðt m i tr ng thái l i c a stream. Nu đưc g i v i đi s m c đnh, nĩ s xố t t c các bit l i (error bits). rdstate() Tr v mt h ng th hi n tình tr ng l i hi n hành. Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 16
  17. • Tốn t ! đưc đ nh ngh ĩa ch ng (overloaded) đ th c hi n cùng ch c n ăng nh ư ph ươ ng th c fail() . Vì v y 2 cách vi t sau là t ươ ng đươ ng: // Cách 1 if ( !cout) { // } // Cách 2 if ( cout.fail() ) { // } • Tốn t chuy n ki u void*() đưc đ nh ngh ĩa ch ng đ cho k t q a th c hi n ng ưc v i tốn t !; Vì v y 2 cách vi t sau là t ươ ng đươ ng: // Cách 1 if (cout) //implicit cast thành ki u T b t k ỳ thích h p l nh if(T) { // } // Cách 2 if ( !cout.fail() ) { // } • Tốn t chuy n ki u void*() khơng t ươ ng đươ ng v i ph ươ ng th c good() bi vì nĩ khơng ki m tra end-of-file . 6.4.4. nh h ưng c a buffering • Ví d sau đây minh ho s nh h ưng c a buffering. ðc ch ươ ng trình, ta cĩ th đốn r ng ch ươ ng trình s ho t đ ng nh ư sau: o In ra màn hình chu i: please wait , o Ch 5 giây, sau đĩ ti p t c in ra màn hình chui: All done . Tuy nhiên ch ưa ch c rng ch ươ ng trình s ho t đ ng nh ư trên. Nguyên nhân là do output đưc buffered , vì th chu i “please wait ” cĩ th khơng đưc xu t ra màn hình ngay; điu này d n t i th i gian ch k t sau khi xu t hi n chu i “please wait ” khơng ph i là đúng 5 giây nh ư ta mong đi: #include #include using namespace std; Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 17
  18. int main( ) { // time() returns the number of seconds elapsed //since midnight (00:00:00), January 1, 1970 time_t tm = time( NULL ) + 5; cout #include using namespace std; int main( ) { // time() returns the number of seconds elapsed //since midnight (00:00:00), January 1, 1970 time_t tm = time( NULL ) + 5; cout #include using namespace std; int main( ) { // time() returns the number of seconds elapsed //since midnight (00:00:00), January 1, 1970 Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 18
  19. time_t tm = time( NULL ) + 5; cout >i; // vi c dùng cin s làm s ch vùng đm c a dịng cout while ( time( NULL ) using namespace std; int iarray[2] = { 99, 10 }; int main() { ofstream ofs ( "C:\\test.dat" , ios_base::binary ); // Exactly 8 bytes written ofs.write( ( char *)&iarray[0], sizeof (int )*2 ); return 0; } Câu h i: • ðon ch ươ ng trình sau s ghi vào file C:\test.dat chu i byte (cĩ th t ): a) 99, 0, 10, 0 b) 99, 0, 13, 10, 0 c) 0, 99, 0, 10 d) 0, 10, 13, 0, 99 e) 99, 0, 0, 0, 13, 10, 0, 0, 0 Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 19
  20. f) 99, 0, 0, 0, 10, 0, 0, 0 #include using namespace std; int iarray[2] = { 99, 10 }; int main( ) { ofstream os( "C:\\test.dat" ); os.write( ( char *) iarray, sizeof ( iarray ) ); return 0; } • Hãy nh p đon ch ươ ng trình trên b ng VC 6.0, ch y th . Sau đĩ, dùng VC 6.0 m file C:\test.dat d ng nh phân đ ki m tra k t q a (các s hi n th trong VC 6.0 d ng s hexa: 99 = 63, 13 = D, 10 = A). ð m m t file d ng nh phân trong VC 6.0 ta thao tác nh ư sau: o Ch n File.Open o Sau đĩ trong combo box Open as, ch n Binary . • Ti sao ta ph i m file C:\test.dat d ng nh phân đ xem k t q a? 6.4.6. ðnh ngh ĩa ch ng tốn t using namespace std; class CDate { int m_nMonth, m_nDay, m_nYear; public : CDate( int m, int d, int y ) { m_nMonth = m; m_nDay = d; m_nYear = y; } friend ostream& operator > ( istream& is, CDate& dt ); }; ostream& operator > ( istream& is, CDate& dt ) { Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 20
  21. is >> dt.m_nMonth >> dt.m_nDay >> dt.m_nYear; return is; } int main( ) { CDate dt( 5, 6, 2006 ); // tháng 5, ngày 6, n ăm 2006 cout > dt; cout > đ dùng cho ki u s ph c (CComplex) . 6.4.7. T to các manipulators khơng đi s • Sinh viên t tìm hi u Bài t p: • ðon ch ươ ng trình sau th c hi n các vi c sau: o In ra màn hình dịng ch : “ I'm an IT student from HCM UTE ”. o Cưi (cĩ âm thanh). Vi c này đưc th c hi n b i manipulator smile . o In ra màn hình dịng ch : “ How about my smile? ”. #include #include using namespace std; ostream& smile( ostream& os ) { os << " :-)" ; for (int i = 0; i < 4; i++) Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 21
  22. { Beep(600, 10); // Kêu t n s 600 Hz, trong 10 mili giây Sleep(300); // D ng l i 300 mili giây } return os << endl; } ios_base& operator <<(ios_base& stream, ios_base& (*FuncPtr)(ios_base&)) { return FuncPtr(stream); } int main( ) { cout<< "I'm an IT student from HCM UTE " <<smile << "How about my smile?"<<endl; return 0; } • Hãy gi i thích s ho t đ ng c a ch ươ ng trình trên. • Hãy quan sát cách t o manipulator smile , tr l i các câu h i sau: o Trong hàm main(), tốn t << (đưc đ nh ngh ĩa ch ng trong đon ch ươ ng trình trên) đưc g i khi nào? ðâu là các đi s đưc truy n vào 2 tham s hình th c c a nĩ? o Nu ta s a l i tốn t << nh ư sau thì ch ươ ng trình trên cịn làm vi c đưc khơng?Gi i thích? ios_base& operator <<(ios_base& (*FuncPtr)(ios_base&), ios_base& stream) { return FuncPtr(stream); } • T vi t m t manipulator cĩ tên recommend xu t ra stream dịng ch : “Th c hành là cách r t t t giúp ta hi u và nh bài hc”. 6.5. Input streams • Sinh viên t tìm hi u nh ư bài t p v nhà. 6.6. Các dịng nh p xu t (input/output streams) • Mt dịng nh p xu t va cĩ th là ngu n, v a cĩ th là đích c a các byte d li u. Hai lp dịng nh p xu t (input/output stream class ) th ưng dùng nh t là fstream và strstream . C hai đ u đưc k th a t l p iostream . • fstream và strstream vùa cĩ các tính n ăng c a lp istream va cĩ các tính n ăng ca l p ostream (vì v y mà chúng cĩ th đưc dùng v a là dịng nh p, v a là dịng xu t). • Lp fstream h tr vi c nh p và xu t t i các file trên đĩa. • Nu cĩ nhu c u v a đ c và vi t trên m t file trong cùng m t ch ươ ng trình, ta cĩ th kh i t o m t đ i t ưng thu c l p fstream đ ph c v nhu c u này. • Ta cĩ th xem m t đ i t ưng thu c l p fstream bao g m 2 đ i t ưng logic: m t dịng nh p và m t dịng xu t. Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 22
  23. • Trong đi t ưng thu c l p fstream cĩ ch a 2 bi n riêng bi t: m t bi n đ xác đnh v trí c n đ c trên file và m t bin đ xác đ nh v trí c n vi t lên file. • Lp strstream h tr vi c input và output đn m t in-memory string . 6.7. T t o các manipulators cĩ đi s • Trong ph n này ta s tìm hi u cách t o các output stream manipulators cĩ đi s , và làm th nào đ s d ng các manipulators này cho các lo i dịng khác nhau. • Manipulator th c ch t là m t hàm (function ) đưc gi vào tham s con tr hàm ca tốn t chèn. 6.7.1. Output-stream manipulators mt đ i s (int ho c long) • Th ư vi n dịng cung c p s n m t t p các macros và template dùng cho vi c t o các manipulators cĩ đi s . Ta s xét tr ưng h p các manipulators cĩ m t đ i s là int ho c long . • ð t o m t output stream manipulator vi m t đ i s int hoc long (gi ng nh ư setw ch ng h n), ta ph i dùng class template _Smanip (đưc đ nh ngh ĩa trong ). • Ví d sau t o m t manipulator mt đ i s int cĩ tên fillblank , manipulator này th c hi n vi c chèn mt s l ưng tùy ý các kho ng tr ng (blanks) vào output stream: #include #include using namespace std; void fb( ios_base& os, int l ) { ostream *pos = dynamic_cast (&os); if (pos) { for ( int i=0; i __cdecl fillblank( int no) { return (_Smanip (&fb, no)); } int main( ) { cout << "10 blanks follow" << fillblank( 10 ) << "AAA.\n" ; return 0; } Output: 10 blanks follow AAA. (10 kho ng tr ng tr ưc ch “AAA”) Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 23
  24. 6.7.2. Các output-stream manipulators mt đ i s khác • Trong ví d sau, ta t o manipulator setpic th c hi n vi c g n m t chu i đ nh dng ti lp CMoney . Manipulator setpic cĩ th đưc s d ng b i tốn t chèn (đã đưc overload) tươ ng thích v i lp CMoney . Chu i đnh d ng đưc l ưu trong mt thành ph n d li u tĩnh trong l p CMoney . #include #include #include using namespace std; typedef char * charp; class CMoney { private : long m_lValue; static char * m_szCurrentPic; public : CMoney( long val ) { m_lValue = val; } friend ostream& operator __cdecl setpic( char * somename) { return (_Smanip (&fb, somename)); } int main( ) { CMoney amt = 35235.22; cout << setiosflags( ios::fixed ); cout<<setpic( "###,###,###.##" )<< "amount = " << amt << endl; return 0; } Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 24
  25. Output: amount = 35235[ ### ,### ,### .## ] Bài t p: • Các đon code d ưi đây là đnh ngh ĩa c a class template _Smanip , function template operator >> , và l p ostream do Microsoft vi t (trích t IDE Microsoft Vistual Studio .Net 2005). Hãy đc hi u các đon code này và gi i thích th t chi ti t cơ ch làm vi c c a 2 ví d trong ph n 6.7.1 và 6.7.2 . template struct _Smanip { // store function pointer and argument value _Smanip( void (__cdecl *_Left)(ios_base&, _Arg), _Arg _Val) : _Pfun(_Left), _Manarg(_Val) {// construct from function pointer and argument value } void (__cdecl *_Pfun)(ios_base&, _Arg); //the function pointer _Arg _Manarg; // the argument value }; template inline basic_ostream & __CLRCALL_OR_CDECL operator & _Ostr, const _Smanip & _Manip) {// insert by calling function with output stream and argument (*_Manip._Pfun)(_Ostr, _Manip._Manarg); return (_Ostr); } typedef basic_ostream > ostream; 6.8. T t o các stream b ng cách k th a stream library • Gi ng nh ư các l p C++ khác, mt stream class cĩ th đưc d n xu t (k th a) đ thêm vào nĩ các ph ươ ng th c m i, các data members mi, ho c các manipulators mi. Ví d n u ta c n m t output file stream vi các tính n ăng m i, ta cĩ th t o mt l p m i k th a t l p ofstream . • Trong l p m i k th a, ta ch c n vi t thêm các constructors, destructor và các ph ươ ng th c m i. • Lp streambuf th c hi n hu h t các vi c cho các các stream class khác. Thơng th ưng, đ t t o m t dịng xu t m i, ng ưi ta k th a m t l p m i t l p streambuf , sau đĩ g n l p này v i l p ostream . • Sinh viên t tìm hi u thêm v ph n này . Biên so n: ð ng Thanh D ũng, khoa CNTT - ðH SPKT TP.HCM 25