ฟังก์ชัน I/O มาตรฐานและ ฟังก์ชันทางคณิตศาสตร์
แบ่งเป็นหัวข้อย่อยดังนี้
- cout กับการแสดงผลบนจอภาพ
- cin และการตรวจสอบข้อมูลจากแป้นพิมพ์
- ฟังก์ชันทางคณิตศาสตร์ที่ควรรู้จัก
- ฟังก์ชันจัดการแฟ้มข้อมูล
ภาษา C++ อำนวยความสะดวกให้ผู้เขียนโปรแกรมสามารถนำข้อมูลแสดงออกทาง output (จอภาพ, เครื่องพิมพ์ , ฯ) หรือรับข้อมูลจาก input (แป้นพิมพ์, พอร์ตต่าง ๆ , หรือไฟล์) ได้โดยง่าย โดยบรรจุฟังก์ชัน และคลาสที่ทำหน้าที่เหล่านี้ไว้ใน standard library (คลังโปรแกรมมาตรฐาน) พร้อมนำไปใช้งานได้ทันที
การแสดงผลออกทางจอภาพ เราได้ใช้คำสั่ง cout (console output) มาแล้วในโปรแกรม 1.1 บทที่ 1
cout << “Area of rectangle = “ << area << endl;
จากประโยคนี้มีการส่งผ่านพารามิเตอร์ (parameter) 3 ค่า ไปยัง cout โดยส่งเรียงไปตามลำดับเป็นกระแสข้อความ (stream – A stream is any flow of data form a producer (source) to a consumer(sink) ) คั่นด้วยเครื่องหมาย << (insertion parameter) cout สามารถแปลงข้อมูลชนิดต่าง ๆ อย่างอัตโนมัติ ไม่ว่าจะเป็นจำนวนเต็ม หรือเลขทศนิยม จะถูกแปลงให้เป็นตัวอักษรแสดงผลเรียงลำดับบนจอภาพ
ก่อนจะใช้ cout แสดงผลบนจอภาพ หรือ cin (console input) รับข้อมูลจากแป้นพิมพ์ จะต้องนำ header file ชื่อ iostream.h ใส่ไว้ตรงส่วนหัวของโปรแกรมเสมอ โดยใช้คำสั่ง #include ในไฟล์ iostream.h จะมีการกำหนดข้อมูลและเครื่องหมายต่าง ๆ สำหรับ cout และ cin นำไปใช้
การแสดงผลอาจใช้ตัวกรองข้อมูล หรือ manipulator ทำหน้าที่กรองกระแสข้อมูลให้ผ่านไปยัง cout ทำให้รู้ว่าจะส่งข้อมูลแสดงผลในลักษณะใด manipulator จะถูกนิยามไว้ใน iostream.h ได้แก่ hex จะเป็นการกำหนดให้พิมพ์ตัวเลขในรูปฐานสิบหก dec พิมพ์จำนวนเลขเป็นเลขฐานสิบ oct พิมพ์จำนวนเลขเป็นเลขฐานแปด
ตัวอย่างการนำไปใช้มีดังนี้
[Source code: Dec2HexO.cpp]
การทำงานของโปรแกรมจะเป็นดังนี้
manipulator นอกจากจะนิยามไว้ใน iostream แล้ว ยังนิยามไว้ใน iomanip ด้วย ที่ใช้บ่อย ๆ ในการแสดงผลจำนวนจริง ได้แก่
setw หมายถึง set field width บอกจำนวนตำแหน่งที่จะแสดงผลบนหน้าจอ สามารถจัดรูปแบบการแสดงผลโดยใช้แทน tab (\t)
ตัวอย่าง เช่น int i = 625;
cout << setw(5) << i;
จะแสดงผลบนจอโดยพิมพ์ตัวเลขชิดขวา เติมช่องว่างด้านหน้าให้อีก 2 ตำแหน่งให้ครบ 5 ตำแหน่ง
_ _ 6 2 5
setprecision เป็นการกำหนดจำนวนตัวเลขหลังจุดทศนิยม โดยปกติจะแสดงตัวเลขหลังจุดทศนิยม 6 ตำแหน่ง
setiosflags จะใช้ในการกำหนดรูปแบบหรือตั้งค่าการแสดงผลและรับข้อมูล ข้อมูลจะคงรูปแบบเช่นนี้ตลอดไปในโปรแกรม จนกว่าจะใช้คำสั่ง resetiosflags ทั้งการแสดงผลและการรับข้อมูลจะมองจาก flag ที่ manipulator กำหนดไว้
flag ที่ใช้ในการแสดงผลมีดังนี้
ios :: right แสดงผลตัวเลขในลักษณะชิดด้านขวา
ios :: left แสดงผลตัวเลขในลักษณะชิดด้านซ้าย
ios :: dec แสดงผลตัวเลขในฐานสิบ เช่นเดียวกับ dec ที่อยู่ในไฟล์ iostream
ios :: oct แสดงผลตัวเลขในฐานแปด เช่นเดียวกับ oct ที่อยู่ในไฟล์ iostream
ios :: hex แสดงผลตัวเลขในฐานสิบหก เช่นเดียวกับ hex ที่อยู่ในไฟล์ iostream
ios :: scientific แสดงผลในรูป exponential เช่น 3.24 จะเขียนในรูป 3.2 e1
ios :: fixed แสดงผลเป็นจำนวนจริงที่มีจำนวนตำแหน่งของเลขทศนิยมคงที่
[Source code: format.cpp]
ผลการรันโปรแกรม ดังรูปข้างล่างนี้
โปรแกรมจะทำงานในขั้นแรก หมายเลข 1 ในรูป จะแสดงผลค่า PI ( PI = 3.141592653) ที่มีตัวเลขหลังทศนิยมต่างกัน ตามที่กำหนดไว้ setprecision( i) โดยกำหนดให้ i มีค่าตั้งแต่ 1 ถึง 10
หมายเลข 2 กำหนดให้การพิมพ์ค่า PI โดยกำหนดความกว้างของ setw(12)
หมายเลข 3 เป็นการพิมพ์ค่า PI ในรูปเลขยกกำลัง
หมายเลข 4 ได้กำหนด flag ไว้เป็น ios :: scientific เมื่อพิมพ์จำนวน 50 พบว่าจะอยู่ในเลขยกกำลัง
หมายเลข 5 เมื่อ reset flag พบว่าสามารถพิมพ์ตัวเลข 50 ในรูปแบบปกติที่เราคุ้นเคย
ข้อมูลที่ป้อนเข้ามาทางแป้นพิมพ์อาจมีการพิมพ์ผิด เช่น ต้องการป้อนข้อมูลตัวเลข อาจมีตัวอักษรปนเข้ามาด้วย เราสามารถตรวจสอบได้โดยใช้คำสั่ง cin ดังนี้
cin.eof( ) ส่งค่า 1 กลับคืนถ้าพบจุดสิ้นสุดของไฟล์ (end of file)
cin.good( ) ส่งค่า 1 กลับคืนถ้าข้อมูลที่รับเข้ามาถูกต้อง
cin.fail ( ) ส่งค่า 1 กลับคืน ถ้าพบว่าข้อมูลที่ป้อนเข้ามามีข้อผิดพลาด
ตัวอย่างเช่น
int i;
cin >> i;
if ( cin.good() ) cout << “ Data ok, value =“ << i << endl;
else
cout << “Data input error !!! “;
………….
กรณีเลือกใช้ cin.fail() ในการตรวจสอบจะเป็นดังนี้
if ( cin.fail () ) cout << “Data Error \n”;
else cout << “ Data ok, value = “ << i << endl;
………….
วิธีการตรวจสอบ อาจใช้สถานะของ stream ในตัวคำสั่งของ cin จะเรียกฟังก์ชัน cin.fail () จะส่งกลับค่า false ถ้ามีข้อผิดพลาด
if ( cin) cout << “ Data OK \n “ ;
else cout << “Data Error \n”;
อาจเขียนคำสั่งตรวจสอบกะทัดรัด พร้อมคำสั่งป้อนข้อมูลก็ได้ดังนี้
if ( cin >> i) cout << “ Data OK = “ << i ;
else cout << “Data error \n “;
โปรแกรม 3.3 เป็นการหาพื้นที่ของวงกลม เมื่อป้อนค่ารัศมี โดยข้อมูลบางค่าเป็นตัวอักษร สังเกตผลลัพธ์ที่ได้
[Source code:Testcin.cpp]
ตัวเลขที่มีกรอบวงกลมสีขาวล้อมรอบนั้นเป็นค่าที่เราป้อนเข้าไปในโปรแกรม ทางแป้นพิมพ์
ในการแก้ปัญหาทางวิทยาศาสตร์และวิศวกรรม สมการที่ได้อาจอยู่ในรูปเลขยกกำลังหรือล็อกการิธึม ฟังก์ชันตรีโกณมิติ ฟังก์ชันเอ็กซโพเนนเชียล ภาษา C++ ได้สร้างฟังก์ชันทางคณิตศาสตร์เตรียมไว้ให้เรียกใช้งานได้ทันที ฟังก์ชันเหล่านี้อยู่ใน standard C++ library การเรียกใช้งานฟังก์ชัน ต้องใส่ประโยค #include <math> ไว้ที่ส่วนหัวของโปรแกรม
ฟังก์ชันทางคณิตศาสตร์พื้นฐานที่ใช้บ่อย ๆ ในงานคำนวณ ได้แก่
ceil (x)
| ปัดจำนวนจริง x ให้มีค่าเพิ่มขึ้นเป็นจำนวนเต็มที่มีค่าใกล้ x และใกล้ค่า ¥ (infinity) มากที่สุด ( smallest integer >= x) or round up เช่น ceil (5.03) = 6 |
exp(x)
| คำนวณค่า e x เมื่อ e เป็นเลขฐานธรรมชาติ e = 2.718282…, exp(e) = 7.38906,,, |
fab(x)
| หาค่าสมบูรณ์ของ x เช่น fab(-6) = 6 |
floor ( x )
| ปัดจำนวนจริง x ให้มีค่าลดลงเป็นจำนวนเต็มที่มีค่าใกล้ x และใกล้ค่า - ¥ มากที่สุด ( largest integer <= x) or round down เช่น floor (5.03) = 5 |
log ( x )
| คำนวณค่า ln x จะเกิดข้อความผิดพลาด ถ้า x น้อยกว่า หรือเท่ากับ 0 เช่น log (2) = 0.693147 |
log10 (x)
| คำนวณค่า log ฐานสิบของ x จะเกิดข้อความผิดพลาด ถ้า x น้อยกว่า หรือเท่ากับ 0 เช่น log10 ( 2) = 0.30103 |
pow (x,p)
| คำนวณค่า x P จะเกิดข้อความผิดพลาด ถ้า x เท่ากับศูนย์ และ P น้อยกว่าศูนย์ หรือถ้า x น้อยกว่าศูนย์ และ P ไม่ใช่เลขจำนวนเต็ม เช่น pow(3,2) = 9.0 |
sqrt ( x )
| คำนวณค่ารากที่สองชอง x จะเกิดข้อความผิดพลาด ถ้า x เป็นจำนวนลบ เช่น sqrt(3)=1.732… |
ฟังก์ชันทางคณิตศาสตร์จะส่งค่ากลับแบบ double ถ้าค่าที่ส่งผ่านในอาร์กิวเมนต์เป็นจำนวนเต็ม จะถูกเปลี่ยนเป็นจำนวนจริงเสียก่อนที่จะนำไปคำนวณ
การใช้งานฟังก์ชันทางคณิตศาสตร์ ทำได้โดยเขียนชื่อฟังก์ชันตามด้วยวงเล็บ ภายในวงเล็บคือค่าคงที่ หรือค่าของตัวแปรที่จะให้ฟังก์ชันนั้นไปใช้ในการคำนวณ อาจจะมีมากกว่า 1 ค่า เช่น pow ( x, y) จะต้องมีค่าคงที่หรือตัวแปรถึง 2 ตัว หรืออาจไม่มีเป็นวงเล็บว่าง ๆ ก็ได้ ค่าที่อยู่ในวงเล็บเรียกว่า parameter หรือ argument ฟังก์ชันใดที่มีพารามิเตอร์มากกว่า 1 ตัว การใส่ค่าพารามิเตอร์จะต้องเรียงลำดับให้ถูกต้อง และตรงกับชนิดข้อมูลที่กำหนดไว้ด้วย
บางครั้งจะต้องระวังเรื่องหน่วยวัดของค่าพารามิเตอร์ด้วย ฟังก์ชันตรีโกณมิติจะรับค่ามุมที่มีหน่วยเป็นเรเดียนเท่านั้น ถ้าข้อมูลมีหน่วยเป็นองศา จะต้องเปลี่ยนค่ามุมที่เป็นองศาให้เป็นเรเดียนเสียก่อน
ตัวอย่างเช่น ต้องการเก็บค่า sin x ไว้ในตัวแปร y โดยที่ x วัดเป็นองศา จะต้องเปลี่ยนค่า x ให้เป็นเรเดียนเสียก่อน โดยใช้ความสัมพันธ์ 180 องศา เท่ากับ p เรเดียน
const double PI = 3.141592653;
:
:
double x, y;
y = sin (x *PI/ 180);
ฟังก์ชันสามารถใช้เป็นตัวพารามิเตอร์ของอีกฟังก์ชันหนึ่งก็ได้ บรรทัดต่อไปนี้คำสั่งหาค่า log ของค่าสมบูรณ์ของ x
y = log (fabs(x));
ฟังก์ชันตรีโกณมิติ
ฟังก์ชันตรีโกณมิติที่มีอยู่ใน standard C++ library มีดังนี้
sin (x)
| คำนวณหาค่า sin x เมื่อ x มีหน่วยเป็นเรเดียน |
cos (x)
| คำนวณหาค่า cos x เมื่อ x มีหน่วยเป็นเรเดียน |
tan (x)
| คำนวณหาค่า tan x เมื่อ x มีหน่วยเป็นเรเดียน |
asin (x)
| คำนวณหาค่า arcsine หรือ inverse sine ของ x x จะมีค่าอยู่ระหว่าง -1 ถึง 1 ฟังก์ชันจะส่งผลลัพธ์กลับเป็นค่ามุมเรเดียน มีค่า - p /2 ถึง p /2 |
acos (x)
| คำนวณหาค่า arccosine หรือ inverse cosine ของ x x จะมีค่าอยู่ระหว่าง -1 ถึง 1 ฟังก์ชันจะส่งผลลัพธ์กลับเป็นค่ามุมเรเดียน มีค่า - p /2 ถึง p /2 |
atan(y,x)
| คำนวณหาค่า arctan หรือ inverse tan ของ y/ x ฟังก์ชันจะส่งผลลัพธ์กลับเป็นค่ามุมเรเดียน มีค่า - p /2 ถึง p /2 |
atan2(y/x)
| คำนวณหาค่า arctan หรือ inverse tan ของ y/ x ฟังก์ชันจะส่งผลลัพธ์กลับเป็นค่ามุมเรเดียน มีค่า - p ถึง p |
ฟังก์ชัน atan จะส่งกลับค่ามุมซึ่งอยู่ในควอแดรนต์ที่ 1 และ 3 ในขณะที่ฟังก์ชัน atan2 จะส่งกลับค่ามุมซึ่งอยู่ในควอแดรนต์ใด ๆ ขึ้นอยู่กับเครื่องหมายของ x และ y ในการแก้ปัญหาทางวิทยาศาสตร์ ควรใช้ฟังก์ชัน atan2
ค่า inverse ของ sine และ cosine จะถูกต้องก็ต่อเมื่อค่าอาร์กิวเมนต์อยู่ในช่วง -1 ถึง 1 เท่านั้น
ตัวอย่าง การใช้ฟังก์ชันคณิตศาสตร์หารากสมการกำลังสองซึ่งอยู่ในรูป ax 2 + bx + c = 0 เมื่อ a,b และ c เป็นสัมประสิทธิ์ของ x รากสมการที่ได้จะมี 2 ค่า คือ
การทำงานเป็นไปตามโฟลว์ชาร์ต ดังต่อไปนี้
[Source code : quadratic.cpp]
ผลการรันโปรแกรม จะได้ดังนี้
Enumeration Type
นอกจากจะมีชนิดข้อมูลแบบจำนวนเต็ม ได้แก่ int และ char ให้ใช้งานแล้ว C++ ยังยอมให้ผู้เขียนโปรแกรมสร้างชนิดข้อมูลในแบบเฉพาะของตนเอง (user- define type) อีกด้วย ซึ่งทำได้หลายวิธี เช่น ใช้ class หรือใช้ชนิดข้อมูลแบบ enumeration type ทำให้โปรแกรมสามารถสื่อความหมายของตัวมันเอง ได้ชัดเจน ซึ่งมีรูปแบบดังนี้
enum ชื่อชนิดข้อมูล { รายการข้อมูลต่าง ๆ ที่จะเป็นสมาชิกของชนิดข้อมูลนี้ };
enum เป็นคำสงวนใน C++ การตั้งชื่อชนิดข้อมูล (typename) ใช้หลักเกณฑ์เดียวกันกับการตั้งชื่อตัวแปร รายการข้อมูล (enumeratorlist) ที่ใส่ในวงเล็บปีกกาจะถูกแทนด้วยจำนวนเต็ม โดยเริ่มต้นที่ศูนย์ ตัวอย่างเช่น
enum Grade { F, D, C, B, A };
เราสามารถนำชนิดข้อมูล Grade ไปใช้งาน ดังนี้
Grade sci_grade, math_grade;
sci_grade = B;
math_grade = A;
if ( sci_grade == math_grade)
cout << “You got the same grade \n”;else
cout << “ You got different grade\n”;
ค่าจำนวนเต็มที่ถูกกำหนดไว้ในรายการข้อมูล เรียกว่า enumerator ซึ่งจะคล้ายกับการนิยามค่าคงที่
const int F =0;
const int D = 1;
: :
const int A = 4;
ค่าที่กำหนดใน enumeratorlist อาจเป็นจำนวนเต็มค่าอื่นที่เราต้องการก็ได้ เช่น
enum Base { binary = 2, octal =8, decimal = 10, hexadecimal = 16 };
หรือกำหนดค่าเริ่มต้นเป็นค่าอื่น ที่ไม่ใช่ศูนย์ เช่น
enum DayOfWeek { sun=1, mon, tue, wed, thu, fri, sat };
sun มีค่าเท่ากับ 1 mon มีค่าเท่ากับ 2 , …, sat มีค่าเท่ากับ 7
สามารถสร้าง enumerator ที่มีค่าซ้ำกันได้ เช่น
enum Answer { false =0, no=0, ture=1, yes=1, ok=1 };
การนำไปใช้ให้ประกาศตัวแปรดังนี้
Answer ans;
:
if (ans) cout << “ Your answer is ok. “;
ไม่ว่าค่า ans จะเป็น true หรือ yes หรือ ok ทุกตัวมีค่าเท่ากับ 1 เงื่อนไขนี้จะเป็นจริงเสมอ
ตัวอย่างอื่น ๆ กับการกำหนดข้อมูลชนิด enumeration type
enum Sex { female, male};
enum CardType { clubs, diamonds, hearts, spades };
enum RainbowColor { violet, blue, green, yellow, orange, red};
enum RomanNumber { I=1, V=5, X= 10, L=50, C=100, D=500, M=1000};
ข้อควรระวัง
1. สมาชิกใน enumeratorlist ไม่สามารถมีเครื่องหมาย + หรือ - ได้เช่น
enum Grade { F, D, D+, C, C+, B, B+, A};
2. ชื่อสมาชิกของข้อมูลชนิด enumeratorlist ที่มากกว่า 2 ชุดขึ้นจะซ้ำกันไม่ได้ เช่น
enum Grade { F, D, C, B, A };
enum RomanNumber { I=1, V=5, X= 10, L=50, C=100, D=500, M=1000};
จากตัวอย่างนี้จะเห็นว่า C และ D จะถูกนิยามสองครั้ง
โปรแกรม 3.5 เป็นตัวอย่างสร้างข้อมูลชนิด enum
[Source code: enum.cpp]
ผลลัพธ์ของ two + three จะมีค่าเหมือน 2 + 3 = 5 อย่างไรก็ตาม mynum ไม่ใช่ข้อมูลชนิด int แต่เป็น number จึงต้อง cast ชนิดข้อมูลด้วย number
ไฟล์หรือแฟ้มข้อมูลใน C++ จัดเป็น stream คือประกอบด้วยบิต (0 หรือ 1) ถูกจัดเก็บเรียงต่อกันในสื่อบันทึกข้อมูล เช่น แผ่นดิสก์ หรือเทป ระบบปฏิบัติการของคอมพิวเตอร์จะตีความหมายบิตทั้งหลายเหล่านี้ในลักษณะต่าง ๆ กัน เช่น ถ้าบิตถูกจัดกลุ่ม ๆ ละ 8 บิต จะถูกแปลความหมายเป็นรหัสอัสกี (ASCII code) ไฟล์นี้จะจัดเป็น text file สามารถเปิดดูได้โดยอาศัยโปรแกรมประเภท text editor ถ้าบิตเหล่านี้ถูกจัดกลุ่ม ๆ ละ 32 บิตแทนพิกเซลของสี ไฟล์นี้จะเป็นไฟล์ประเภทกราฟิก ต้องใช้โปรแกรมประเภทกราฟิก เช่น paint หรือ photoshop เปิดดูข้อมูล ถ้าไฟล์นั้นเป็นชุดคำสั่งของคอมพิวเตอร์ เช่นมีนามสกุล เป็น exe หรือ com บิตจะถูกแปลความหมายเป็น คำสั่งของคอมพิวเตอร์ หน่วยประมวลผลกลางหรือ cpu จะนำไปประมวลผลต่อไป
ถ้าไฟล์นั้นถูกใช้งานสำหรับเขียนข้อมูลหรือแสดงข้อมูลออกทางจอภาพหรือเครื่องพิมพ์ จะเรียกเป็น output file stream ถ้าไฟล์นั้นถูกเปิดขึ้นมาเพื่ออ่านข้อมูลจากไฟล์นำเข้าไปสู่หน่วยความจำของคอมพิวเตอร์จะเรียกว่า input file stream การใช้งานแฟ้มข้อมูลจะต้องอ้างไฟล์ fstream.h ไว้ที่ส่วนต้นของโปรแกรม ในไฟล์ fstream.h นี้จะมีการนิยามคลาส ofstream และ ifstream สำหรับใช้กับ output file stream และ input file stream ตามลำดับ instance ของคลาสเหล่านี้จะใช้เครื่องหมาย << (insertion operator) และ เครื่องหมาย >> (extraction operator) เหมือนกับ stream อื่น ๆ
ภาพต่อไปนี้แสดงความสัมพันธ์ระหว่าง stream กับสิ่งที่เกี่ยวข้อง อาจมอง stream เหมือนกับท่อน้ำที่นำข้อมูลเข้าหรือออกจากโปรแกรมไปยังต้นทางหรือปลายทาง (from page 396 Schaum's outline)
ในกรณีข้อมูลที่ใช้ในการคำนวณมีปริมาณมาก การป้อนข้อมูลเข้าทางแป้นพิมพ์ย่อมไม่สะดวก หรือบางครั้งข้อมูลที่ได้ ได้มาจากเครื่องมือวัด (probe or sensor) ซึ่งเก็บข้อมูลตามระยะเวลาที่กำหนด ข้อมูลที่เก็บได้จะถูกบันทึกไว้ในรูปแฟ้มข้อมูล โปรแกรมสามารถดึงข้อมูลจากแฟ้มนั้นมาประมวลผลได้ทันที
การเขียนโปรแกรมที่ใช้งานแฟ้มข้อมูลจะต้องกำหนดไฟล์ส่วนหัว (header file) ไว้ดังนี้
#include <fstream>
ไฟล์ fstream.h จะเก็บข้อมูลที่เกี่ยวข้องกับการจัดการกับแฟ้มข้อมูล ก่อนที่แฟ้มข้อมูลแต่ละแฟ้มจะถูกสร้างขึ้นมา จะต้องกำหนดเป็นชนิดข้อมูลที่เรียกว่า file object สำหรับใช้ในการติดต่อกับแฟ้มข้อมูล เช่นเราจะสร้างไฟล์ ชื่อ data1.dat เพื่อไว้เก็บข้อมูล จะต้องกำหนด file object ชื่อว่า myfile (การกำหนดชื่อ file object เป็นไปตามเงื่อนไขเดียวกับ identifier ข้อสำคัญต้องสื่อความหมายและอ่านง่าย) ไว้ใช้ติดต่อเชื่อมโยงกับไฟล์ดังกล่าว โดยกำหนดดังนี้
fstream myfile;
file object ชื่อ myfile ที่กำหนดชึ้นมานี้ จะถูกนำไปใช้จัดการกับไฟล์ data1.dat โดยใช้ฟังก์ชัน open ซึ่งประกอบด้วยอากิวเมนต์ (argument) 2 ตัวคือ
fstream object_name;
object_name.open ( “filename”, access_mode);
สามารถเขียนรวมเป็นบรรทัดเดียวกันได้ดังนี้
fstream object_name (“filename”, access_mode);
อากิวเมนต์ตัวแรกเป็นชื่อไฟล์ ปิดหัวท้ายด้วยเครื่องหมาย “ .. ” (double quotes) ตัวที่สอง จะใช้บอกสถานะไฟล์หรือลักษณะการเข้าถึงตัวไฟล์ (access mode) ว่าจะบันทึกข้อมูลลงในไฟล์ หรืออ่านข้อมูลจากไฟล์นั้น
ถ้าต้องการอ่านข้อมูลจากไฟล์ จะต้องกำหนดสถานะเป็น ios:: in ถ้าต้องการจะเขียนข้อมูลลงในไฟล์ จะต้องกำหนดเป็น ios: :out
ถ้าเราต้องการอ่านข้อมูลที่เก็บไว้ใน data1.dat จะต้องเขียนคำสั่งในโปรแกรมดังนี้
myfile. open ( “data1.dat”, ios :: in);
เมื่อกำหนดชื่อไฟล์และสถานะของไฟล์แล้ว เราสามารถนำข้อมูลจากไฟล์มาใช้ในการคำนวณ แทนที่จะต้องป้อนผ่านแป้นพิมพ์ที่ละค่า ซึ่งจะทดลองทำดังต่อไปนี้
ขั้นแรกให้เปิดโปรแกรมประเภท editor เช่น Notepad ในวินโดว์ หรือ edit ใน DOS พิมพ์คะแนนของนักศึกษา 12 คน ดังนี้
ข้อมูลบรรทัดแรกเป็นจำนวนนักศึกษา ข้อมูลในบรรทัดที่ 2 และ 3 จะเป็นคะแนนของนักศึกษาทั้ง 12 คน จัดเก็บข้อมูลนี้ในไฟล์ชื่อ data1.dat โดยเก็บไว้ในโฟลเดอร์ที่เราจะสร้าง execute file จากนั้นเขียนและคอมไพล์โปรแกรมต่อไปนี้
[Source code: FindAv2.cpp]
ผลการรันโปรแกรมจะเป็นดังนี้
เราสามารถนำข้อมูลจากไฟล์มาเก็บไว้ในตัวแปรโดยใช้เครื่องหมาย >> (คล้ายกับ cin) ซึ่งเป็นการรับข้อมูล
myfile >> num;
เป็นการนำข้อมูลค่าแรก (คือ 12 ) มาเก็บไว้ในตัวแปร num จากนั้นวนรอบอีก 12 ครั้ง เพื่ออ่านคะแนนเข้ามาเก็บไว้ในตัวแปร score เมื่ออ่านข้อมูลจากไฟล์ครบแล้ว ต้องปิดแฟ้มข้อมูลก่อนจบโปรแกรมเสมอ โดยใช้คำสั่ง
myfile.close ();
โปรแกรม 3.7 เป็นการนำข้อมูลที่ได้จากการวัดอุณหภูมิเป็นองศาเซลเซียสที่เวลาต่าง ๆ กัน ข้อมูลจะถูกบันทึกไว้ในแฟ้มข้อมูล ขื่อ temp.dat มาหาค่าเฉลี่ย ค่าสูงสุด ค่าต่ำสุด
ข้อมูลที่ได้มีจำนวนหลายรายการ (record) เช่นรายการที่ 1 เมื่อเวลา 5.20 น.วัดอุณหภูมิได้ 23 องศาเซลเซียส ข้อมูลเหล่านี้อาจได้จากหัววัดอุณหภูมิ หรือเครื่องตรวจวัดอุณหภูมิ จำนวนรายการที่วัดได้มีจำนวนเท่าใดนั้น จะใช้ฟังก์ชัน eof () ( end of file) ตรวจสอบหาจุดสิ้นสุดของไฟล์ จากนั้นจะหาค่าเฉลี่ย ค่าสูงสุด และค่าต่ำสุดของอุณหภูมิ ในช่วงเวลาที่เก็บข้อมูล
[Source code : temp.cpp]
ผลของการรันโปรแกรม เป็นดังภาพ
ทดลองพลิกแพลงเพื่อตรวจสอบการอ่านไฟล์ของภาษา C++
จากโปรแกรม 3.7 จะเห็นว่าจะมีการอ่านค่าเวลาและอุณหภูมิมาเก็บไว้ที่ตัวแปร time , temp ในบรรทัดที่ 22 ก่อน แล้วจึงมีการวนรอบเพื่อตรวจสอบจุดสิ้นสุดของไฟล์ จากนั้นจึงเป็นการอ่านค่าเวลา และอุณหภูมิของรายการที่เหลือ ในบรรทัดที่ 37 บรรทัดที่ 36 (ทำเป็น comment ไว้) จะไว้ใช้ตรวจสอบข้อมูลที่อ่านเข้ามา ว่าถูกต้องหรือไม่
ถ้าจะพลิกการอ่านข้อมูลจากไฟล์ให้เป็นแบบอื่น ๆ บ้างดังตัวอย่างต่อไปนี้
1: // Program 3.8 temp 2. cpp
2: // Read data from file , temp.dat
3: #include <iostream>
4: #include <fstream>
5: using namespace std;
6:
7: main() {
8: int num= 0 ;
9: double time;
10: double temp;
11: double max, min, average, maxtime, mintime;
12: double sum;
13: fstream myfile;
14:
15: sum = max =average = 0 ;
16: min = 1000 ;
17: myfile.open("temp.dat", ios::in);
18: if (myfile.fail() ) {
19: cout << "Error opening temp.dat\n";
20: return 1 ;
21: }
22: while (!myfile.eof()) {
23: myfile >> time >> temp;
24:
25: sum = sum + temp;
26: if (temp > max) {
27: maxtime = time;
28: max = temp;
29: }
30: if ( temp < min ) {
31: mintime = time;
32: min = temp;
33: }
34: num++;
35:
36: cout << num << " " << time << " " << temp << endl;
37: }
38: average = sum/num;
39:
40: cout << "The number of record = " << num << endl;
41: cout << "Max temperature is " << max
42: << " at time = " << maxtime << endl;
43: cout << "Min temperature is " << min
44: << " at time = " << mintime << endl;
45:
46: cout << "Average temperature = " << average << endl;
47: myfile.close();
48: return 0 ;
49:
50: }
51:
[Source code: temp2.cpp]
จากตัวอย่างนี้จะเห็นว่า จะทำการอ่านข้อมูลสุดท้าย 2 ครั้ง ทำให้จำนวนข้อมูลกลายเป็น 20 รายการ ผลที่ตามมาคือคำนวณค่าเฉลี่ยผิดพลาด
ทดสอบโดยการเปลี่ยนคำสั่งบางคำสั่ง ดังที่พิมพ์ไว้ด้วยตัวหนา ในโปรแกรม temp3.cpp
1: // Program 3.9: temp 3. cpp
2: // Read data from file , temp.dat
3: #include <iostream>
4: #include <fstream>
5: using namespace std;
6:
7: main() {
8: int num= 0 ;
9: double time;
10: double temp;
11: double max, min, average, maxtime, mintime;
12: double sum;
13: fstream myfile;
14:
15: sum = max =average = 0 ;
16: min = 1000 ;
17: myfile.open("temp.dat", ios::in);
18: if (myfile.fail() ) {
19: cout << "Error opening temp.dat\n";
20: return 1 ;
21: }
22: while (myfile >> time >> temp) {
23:
24: sum = sum + temp;
25: if (temp > max) {
26: maxtime = time;
27: max = temp;
28: }
29: if ( temp < min ) {
30: mintime = time;
31: min = temp;
32: }
33: num++;
34:
35: cout << num << " " << time << " " << temp << endl;
36: }
37: average = sum/num;
38:
39: cout << "The number of record = " << num << endl;
40: cout << "Max temperature is " << max
41: << " at time = " << maxtime << endl;
42: cout << "Min temperature is " << min
43: << " at time = " << mintime << endl;
44:
45: cout << "Average temperature = " << average << endl;
46: myfile.close();
47: return 0 ;
48:
49: }
50:
[Source code: temp3.cpp]
ผลการรันโปรแกรม พบว่าเป็นไปอย่างถูกต้อง ดังรูป
การบันทึกข้อมูลลงในแฟ้มข้อมูล
การบันทึกข้อมูลเก็บไว้ในแฟ้มข้อมูลก็เหมือนกับการแสดงผลที่จอภาพ ต่างกันตรงที่ข้อมูลถูกเขียนลงในแผ่นดิสก์ การบันทึกข้อมูลต่อไปนี้จะบันทึกเฉพาะตัวข้อมูลล้วน ๆ ไม่มีส่วนหัวที่ใช้บอกจำนวน record หรือส่วนท้ายของข้อมูล
ตัวอย่าง การบันทึกข้อมูลต่อไปนี้จะบันทึกค่าความสูงและระยะไกลของวัตถุ ที่มีการเคลื่อนที่แบบวิถีโค้งภายใต้แรงโน้มถ่วงของโลกที่เวลาต่าง ๆกัน โดยเพิ่มเวลาช่วงละ 0.5 วินาที กำหนดให้ความเร็วต้นของวัตถุเท่ากับ 24 m/s ทำมุม 60 องศากับแนวราบ สมการความเร็วและการกระจัดที่เวลา t ใด ๆ เป็นไปตามสมการต่อไปนี้
[Source code: Projectile.cpp]
เมื่อให้โปรแกรมทำงาน ผลลัพธ์ที่คำนวณได้และจะถูกเก็บไว้ในไฟล์ชื่อ prj.dat แสดงออกที่จอภาพดังรูป
เมื่อเปิดไฟล์ prj.dat ด้วยโปรแกรม editor ในที่นี้ใช้ notepad จะเห็นข้อมูลที่เก็บไว้ดังภาพ
แบบฝึกหัดที่ 3
1. จงหาค่าที่ได้จากคำสั่งต่อไปนี้
floor (-2.6)
ceil (-2.6)
pow(2, -3)
sqrt(floor(10,7))
2. การหดสั้นของความยาว (Length contraction) ในทฤษฎีสัมพัทธภาพพิเศษของไอน์สไตน์ มีดังนี้
length =
เมื่อ คือความยาวขอววัตถุเมื่ออยู่นิ่งเทียบกับผู้สังเกต
v คือความเร็วชองวัตถุ
c คือความเร็วของแสงในสุญญากาศ เท่ากับ m/s
จงเขียนสมการนี้ให้อยู่ในรูปนิพจน์คณิตศาสตร์ของคำสั่งในภาษา C++ จากนั้นเขียนเป็นโปรแกรม ป้อนค่า , v ผ่านทางแป้นพิมพ์แล้วคำนวณหาค่า length
3. จงหาพื้นที่ของสามเหลี่ยมที่มีด้านแต่ละด้านยาว a, b,c โดยใช้สูตร
area =
เมื่อ s =
โดยให้โปรแกรมหยุดรอรับค่า a, b และ c จากแป้นพิมพ์
4. พิสัย (Range, R) ของมวลชิ้นหนึ่งที่เคลื่อนที่แบบวิถีโค้งภายใต้แรงดึงดูดของโลก หาได้จากสมการ
เมื่อ u คือความเร็วต้นของมวล
คือมุมของ u กับพื้นดิน
g = 9.8 m/s 2
ให้ป้อนค่าความเร็วต้น (u) และมุมที่ยิงสู่อากาศ
5. logarithm ของ x ฐาน b หาได้จาก
จงเขียนโปรแกรมพิมพ์ค่า log ฐาน 2 เช่น
6. จงแปลงคำสั่งในภาษา C++ ต่อไปนี้ให้เป็นนิพจน์ทางคณิตศาสตร์
• dm = m* (sqrt(1+v/c)/sqrt(1 – v/c)-1);
• volume = PI * r * r *h;
• P = atan2(z, sqrt(x*x + y*y));
7. ให้ n เป็นจำนวนเต็ม (integer) x เป็นจำนวนจริง (floating point number) คำสั่งต่อไปนี้ต่างกันอย่างไร
n = x;
และ n = static_cast<int> (x +0.5);
x มีค่าเท่าใด จึงจะได้ผลลัพธ์จากทั้งสองคำสั่งเหมือนกัน และ x มีค่าเท่าใด ที่ทำให้ผลลัพธ์แตกต่างกัน และจะเป็นอย่างไรถ้า x ติดลบ
8. จงอธิบายความแตกต่างระหว่าง
2, 20, “2”, “2.0”
9. ผลลัพธ์จากคำสั่งต่อไปนี้ เป็นอย่างไร
x = 2;
y = x + x;
และ
s = “2”;
t = s + s;
10. ต่อไปนี้ จริงหรือเท็จ
ก. x และ “x” มีค่าเท่ากัน ถ้า x เป็นจำนวนเต็ม
ข. static_cast <int> (static_cast<double>(x) จะมีค่าเท่ากับ x ถ้า x เป็นจำนวนเต็ม
ค. s.substr(0, s.length()) มีค่าเท่ากับ s
11. จงอธิบายความแตกต่างระหว่างการป้อนข้อมูลเป็นคำ (word oriented) และเป็นบรรทัด (line oriented) ในภาษา C++ ทำได้อย่างไร เมื่อใดจะใช้แบบไหน
12. จงหา syntax error จากโปรแกรมต่อไปนี้ ( 5 แห่ง)
1: #include iostream
2: int main();
3: { cout << "Enter your number : "
4: cin >> a, b;
5: cout << "The sum of << a << " and" << b
6: << " is " << a+b << endl;
7: return;
8: }
9:
[เฉลย บรรทัดที่ 1 ต้องมี <iostream> และมีคำสั่ง using namespace std;
บรรทัดที่ 2 หลังคำสั่ง main() ต้องไม่มี ;
บรรทัดที่ 4 ต้องประกาศตัวแปร a, b และต้องเปลี่ยนเป็น cin >> a >> b ;
บรรทัดที่ 7 แก้เป็น return 0; ]
13. จงหา logic error ของโปรแกรมต่อไปนี้ ( 3 แห่ง)
1: #include <iostream>
2: using namespace std;
3:
4: int main();
5: {
6: int total;
7: int x1, x2;
8: cout << "Enter your number : ";
9: cin >> x1;
10: total = total + x1;
11: cout << "Enter another number : ";
12: cin >> x2;
13: total = total +x1;
14: float average = total/2;
15: cout << "The average of the two number is " << average << endl;
16:
17: return 0;
18:
19: }
[ เฉลย บรรทัดที่ 10 ต้อง initialize ค่า total ก่อนนำไปใช้งาน
บรรทัดที่ 13 ควรเป็น total = total + x2
บรรทัดที่ 14 มีการคำนวณโดยใช้ข้อมูลต่างชนิดกัน โดยไม่มีการ casting ]