本文轉載自——武特學長的博客——博客地址:http://www.edsionte.com (裏面還有很多的好文章,希望大家能多學習)
看了好一段Linux下的C編程,很多東西都有了一定的瞭解。但是就是有一點比較含糊,那就是Linux下c的錯誤處理。裏面有很多系統函數,也有一些是自己編寫的錯誤處理函數my_err()。就光這點,把我弄迷糊了。今天小組開會時,他們給我說,武特學長博客上面有這方面的講解。下來看了下,確實收穫很多。現在趕緊將這篇文章轉載到我的博客上,希望能有更多的人學習。在這裏,也謝謝武特學長。
————————————————————————————————————————————————————————————————
本文中的錯誤是指在代碼編譯完全正確程序可運行的情況下,因爲沒有成功調用程序中的某些系統調用函數而產生的錯誤。往往這些系統調用函數通過返回值(比如1,0,-1)來說明其是否調用成功,而程序員需要知道詳細的錯誤信息,因此自建錯誤捕獲函數很有必要。 (1)errno和strerror() errno它是一個整形的錯誤代碼。當發生錯誤的時候,系統自動將錯誤代碼賦給errno。使用下面的方法可以獲得具體的錯誤描述: 其中char *strerror(int errnum);是通過errnum來獲取錯誤描述,errnum即所傳遞的errno。該函數末尾的exit(1)使得程序發生錯誤時退出。但應該包含庫函數stdlib.h。 下面進行測試,測試程序(源代碼在本文末尾。)使用open()函數創建文件,因爲要創建的文件已存在,而且使用了O_EXCL參數,因此open()會產生錯誤。結果如下: 該方法可以詳細顯示錯誤信息以及錯誤代碼。但不能顯示錯誤出現的行數。 (2)perror() 其函數原型爲:void perror(const char *s)。s一般是函數名。該函數會先將函數名打印出來,然後再打印出錯誤信息。錯誤信息與errno相對應。第二個參數__LINE__是一個宏,表示當前的行數。使用方法: 測試結果如下: 該方法可以顯示錯誤信息以及錯誤出現的行數。 以上方法是在《linux C編程》中常用的方法,我適當的作了小調整。現在將這兩種方法結合起來: 測試結果如下: 這樣就可以顯示錯誤代碼,錯誤描述,錯誤出現的行數以及出現錯誤的函數。對於和我一樣的新手來說,這裏特別要注意的是宏__LINE__
前後的那個橫線是兩個連續的下劃線,而不是_LINE_
,否則會出現錯誤。
01
void
my_err(
int
error)
02
{
03
printf
(
"error: %s with errno: %d/n"
,
strerror
(error),error);
04
exit
(1);
05
}
06
07
int
main()
08
{
09
..............
10
my_err(
errno
);
11
..............
12
13
}
1
edsionte@edsionte-laptop:~/code$ ./error
2
error: File exists with
errno
: 17
01
void
my_err2(
const
char
* err_string,
int
line)
02
{
03
fprintf
(stderr,
"error: line:%d "
,line);
04
perror
(err_string);
05
exit
(1);
06
}
07
}
08
09
int
main()
10
{
11
.................
12
my_err2(
"open"
,__LINE__);
13
................
14
15
}
1
edsionte@edsionte-laptop:~/code$ ./error
2
error: line:29 open: File exists
3
}
01
void
my_err3(
const
char
* err_string,
int
line,
int
error)
02
{
03
printf
(
"error: line:%d %s():%s with errno:%d/n"
,line,err_string,
strerror
(error),error);
04
exit
(1);
05
}
06
07
int
main()
08
{
09
................
10
my_err3(
"open"
,__LINE__,
errno
);
11
................
12
13
}
1
edsionte@edsionte-laptop:~/code$ ./error
2
error: line:30 open():File exists with
errno
:17
源代碼如下:
說明:本程序只作測試用,爲了同時顯示三種錯誤捕獲函數的信息,因此屏蔽了每個函數的exit(1)。另外本文頭文件函數用“”是因爲顯示問題,沒有什麼特別意義。
01
#include "errno.h"
02
#include "fcntl.h"
03
#include "unistd.h"
04
#include "stdlib.h"
05
#include "stdio.h
06
#include "sys/types.h"
07
#include "sys/stat.h"
08
#include "string.h"
09
10
void
my_err(
int
error)
11
{
12
printf
(
"error: %s with errno: %d/n"
,
strerror
(error),error);
13
// exit(1);
14
}
15
void
my_err2(
const
char
* err_string,
int
line)
16
{
17
fprintf
(stderr,
"error: line:%d "
,line);
18
perror
(err_string);
19
// exit(1);
20
}
21
void
my_err3(
const
char
* err_string,
int
line,
int
error)
22
{
23
printf
(
"error: line:%d %s():%s with errno:%d/n"
,line,err_string,
strerror
(error),error);
24
// exit(1);
25
}
26
int
main()
27
{
28
int
fd;
29
if
((fd=open(
"example_test.c"
,O_CREAT|O_EXCL,S_IRUSR|S_IWUSR))==-1)
30
{
31
my_err(
errno
);
32
my_err2(
"open"
,__LINE__);
33
my_err3(
"open"
,__LINE__,
errno
);
34
}
35
close(fd);
36
return
0;
37
}