Error handling

What is Error handling?

Error handing คือ การจัดการข้อผิดพลาด ซึ่งเป็นความผิดพลาดที่โดยทั่วไปแล้วไม่สามารถจัดการภายในโปรแกรม เมื่อเกิด Error ขึ้นอาจส่งผลให้การทำงานของโปรแกรมล้มเหลว เช่น หน่วยความจำไม่พอ เวอร์ชันการทำงานของ library ไม่ถูกรองรับ การเปิดไฟล์ที่ไม่มีอยู่จริง เป็นต้น จึงต้องมีการเขียน Error handling เพื่อแสดงสาเหตุของข้อผิดพลาดนั้นและทำให้โปรแกรมสามารถทำงานต่อไปได้

Different methods of Error handling

การเขียนโปรแกรมภาษา C ไม่ได้มีการสนับสนุนการจัดการข้อผิดพลาด (Error handling) โดยตรง ผู้ออกแบบโปรแกรมต้องทำการเขียนขึ้นมาเอง โดยการใช้คำสั่ง return ส่งคืนค่า -1 หรือ NULL ในกรณีที่เกิดข้อผิดพลาด และสามารถเขียน Error handling ด้วยการใช้ 'คำสั่ง if' ดังตัวอย่าง การหารด้วย 0 (Divide by Zero Errors) ดังต่อไปนี้
สำหรับภาษา C++ จะมีตัวสนับสนุนการจัดการข้อผิดพลาด เรียกว่า Exceptions handling ถึงแม้ว่าจะมีตัวสนับสนุนจัดการข้อผิดพลาด แต่ก็สามารถเขียน Error handling ได้เหมือนภาษา c
Example code C
Example code C++
// err_p1_1.c
#include <stdio.h>
int solution(int a,int b)
{
if (b > 0) {
return a / b;
}
return -1;
}
int main() {
printf("%d\n",solution(102,0));
printf("%d\n",solution(955,5));
printf("%d\n",solution(1650,2));
return 0;
}
// err_p1_2.cpp
#include <iostream>
using namespace std;
int myFunction(int a,int b) {
if (b == 0) {
return -1;
}
return a/b;
}
int main() {
cout << myFunction(102,0) << endl;
cout << myFunction(955,5) << endl;
cout << myFunction(1650,2) << endl;
return 0;
}
Output
-1
191
825
อย่างที่รู้กันว่าโปรแกรมคอมพิวเตอร์จะไม่สามารถคำนวณค่าที่เกิดจากการหารด้วย 0 เนื่องจากจะส่งผลให้เกิดข้อผิดพลาดในการทำงานและไม่สามารถทำงานต่อไปได้ แต่จากตัวอย่างจะเห็นได้ว่าโปรแกรมสามารถทำงานต่อไปได้ด้วยการเขียน Error handling return ค่า -1
ข้อเสียของการส่งค่า return คือ จะทำให้คนอื่นนอกจากผู้ออกแบบโปรแกรมไม่ทราบว่าค่า -1 ที่ถูก return กลับมานั้นเกิดจากสาเหตุอะไร จึงได้มีการตั้งค่ารหัสตัวแปรส่วนกลาง (Global Variable) เพื่อระบุว่ารหัสตัวแปรที่ปรากฏเกิดจากสาเหตุอะไร ซึ่งสามารถค้นหารหัสตัวแปรข้อผิดพลาดต่าง ๆ ที่กำหนดไว้จาก <errno.h> ที่เป็น header file เรียกวิธีนี้ว่า Global Variable errno

Global Variable errno

Global Variable errno ถูกตั้งค่าเป็นตัวแปรส่วนกลางและระบุว่ามีข้อผิดพลาดอะไรที่เกิดขึ้นระหว่างการเรียกใช้ฟังก์ชันใด ๆ ซึ่งสามารถค้นหารหัสตัวแปรข้อผิดพลาดที่กำหนดไว้จาก <errno.h> (ภาษา C++ สามารถเรียกใช้ได้ทั้งแบบ <errno.h> และแบบ <cerrno>) ดังนั้นโปรแกรมเมอร์สามารถตรวจสอบค่าที่ส่งคืนและสามารถดำเนินการที่เหมาะสมโดยขึ้นอยู่กับค่าที่ส่งคืน ดังตารางต่อไปนี้
errno value จะไม่มีเลข 0 เนื่องจากเลข 0 หมายถึงไม่มีข้อผิดพลาดในโปรแกรม
Example code C
Example code C++
// err_p1_3.c
#include <stdio.h>
#include <errno.h>
int main()
{
// If a file is opened which does not exist,
// then it will be an error and corresponding
// errno value will be set
FILE * fp;
// opening a file which does
// not exist.
fp = fopen("text.txt", "r");
printf(" Value of errno: %d\n ", errno);
return 0;
}
// err_p1_4.cpp
#include <iostream>
#include <cerrno>
using namespace std;
int main()
{
cout << "Attempting file access..." << endl;
FILE *f = fopen("text.txt","r");
if (f == NULL)
{
cout << "Something went wrong! errno : " << errno << endl;
}
return 0;
}
Output
Value of errno: 2
จากตัวอย่างจะเห็นว่าค่าตัวแปร errno ที่ถูกส่งออกมา คือ 2 หมายความว่า โปรแกรมไม่สามารถเปิดไฟล์ที่ต้องการ เนื่องจากไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว
ข้อเสียของการให้ส่งค่าตัวแปรแสดงข้อผิดพลาดเพียงอย่างเดียว คือจะทำให้เกิดความยุ่งยากในการหาคำอธิบายข้อผิดพลาด ดังนั้นจึงได้มีฟังก์ชัน perror() และ strerror() เข้ามาช่วยในการแสดงข้อผิดพลาด
คำถาม คำสั่ง FILE *fp และ fopen คืออะไร
คำตอบ เป็นรูปแบบการประกาศแฟ้มข้อมูลและเปิดแฟ้มข้อมูล
ข้อมูลอ่านเพิ่มเติม :: พื้นฐานการทำงานของไฟล์

perror() and strerror()

  • perror() ย่อมาจาก print error เป็นฟังก์ชันที่ใช้ในการแสดงข้อความของค่า errno ปัจจุบัน โดยที่สามารถแสดงข้อความที่กำหนดไว้ ก่อนการแสดงข้อผิดพลาด
Syntax
void perror (char*msg);
msg คือ ข้อความแบบกำหนดเองก่อนการแสดงข้อผิดพลาด
Example code C
Example code C++
// err_p1_5.c
// C program to illustrate the
// use of perror()
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
// Driver Code
int main()
{
FILE* fp;
// Now try to open same file
fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Error: ");
return (-1);
}
// Close the file pointer
fclose(fp);
return (0);
}
// err_p1_6.cpp
// C++ program to illustrate the
// use of perror()
#include <iostream>
#include <errno.h>
// Driver Code
int main()
{
FILE* fp;
fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Error: ");
return (-1);
}
// Close the file pointer
fclose(fp);
return (0);
}
output
Error: : No such file or directory
  • strerror() คือ ฟังก์ชันที่ใช้รับค่าตัวแปรของ errno เพื่อ return ข้อมูลประเภท string มาแสดงผลข้อผิดพลาด
Example code C
Example code C++
// err_p1_7.c
// C program to illustrate the
// use of strerror()
#include <errno.h>
#include <stdio.h>
#include <string.h>
// Driver Code
int main()
{
FILE* fp;
fp = fopen("file.txt", "r");
if (fp == NULL) {
printf("Value of errno: %d\n ", errno);
printf("The error message is : %s\n",strerror(errno));
return (-1);
}
// Close the file pointer
fclose(fp);
return (0);
}
// err_p1_8.cpp
// C++ program to illustrate the
// use of strerror()
#include <iostream>
#include <cerrno>
#include <string.h>
using namespace std;
// Driver Code
int main()
{
FILE* fp;
// Now try to open same file
fp = fopen("file.txt", "r");
if (fp == NULL) {
cout <<"Value of errno: " << errno << endl;
cout << "The error message is : " << strerror(errno) << endl;
return (-1);
}
// Close the file pointer
fclose(fp);
return (0);
}
Output
Value of errno: 2
The error message is : No such file or directory
นอกจากนี้ยังมีฟังก์ชัน ferror() และ clearerr() ที่ใช้ในการตรวจจับข้อผิดพลาดในการ stream
ศึกษาเพิ่มเติม :: Error handling during file operations in C/C++

Exit Status

Exit Status จะต่างจาก errno, perror() และ strerror() ที่เป็นการแสดงผลข้อผิดพลาด เพื่อให้โปรแกรมสามารถทำงานต่อไปได้ แต่ Exit Status เป็นคำสั่งที่ใช้ในการออกจากโปรแกรม แบ่งออกเป็น 2 ประเภท คือ Exit Success และ Exit Failure ซึ่งต้องทำการ include ก่อน จึงจะสามารถใช้คำสั่ง exit()
1. Exit Success คือ การออกจากโปแกรมที่ไม่เกิดข้อผิดพลาด สามารถเลือกใช้ได้ 2 แบบ ดังต่อไปนี้
Syntax
exit(EXIT_SUCCESS)
exit(0)
สร้างไฟล์ file.txt ก่อน run code ดังต่อไปนี้
Example code C
Example code C++
// err_p2_1.c
#include <stdio.h>
#include <stdio.h>
int main()
{
FILE* file;
// opening the file in read-only mode
file = fopen("file.txt", "r");
printf("File opening successful!");
// EXIT_SUCCESS
exit(0);
}
// err_p2_2.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
FILE* file;
// opening the file in read-only mode
file = fopen("myFile.txt", "r");
cout << "File opening successful!" << endl;
// EXIT_SUCCESS
exit(0);
}
Output
File opening successful!
2. Exit Failure คือ การออกจากโปรแกรมที่เกิดข้อผิดพลาด สามารถเลือกใช้ได้ 2 แบบ ดังต่อไปนี้
Syntax
exit(EXIT_FAILURE)
exit(1)
Example code C
Example code C++
// err_p2_3.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* file;
// open the file in read-only mode
file = fopen("myFile.txt", "r");
if (file == NULL) {
printf("Error in opening file\n");
// EXIT_FAILURE
exit(1);
}
// EXIT_SUCCESS
exit(0);
}
// err_p2_4.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
FILE* file;
// open the file in read-only mode
file = fopen("myFile.txt", "r");
if (file == NULL) {
cout << "Error in opening file" << endl;
// EXIT_FAILURE
exit(1);
}
// EXIT_SUCCESS
exit(0);
}
สำหรับ exit(EXIT_FAILURE) สามารถใช้จำนวนเต็มอื่นที่ไม่ใช่ 1 เพื่อระบุข้อผิดพลาดประเภทต่างๆ
แหล่งอ้างอิง ::
Advance Innovation Center, Electrical Engineering Department, Faculty of Engineering, Burapha University