詳解C說話中的毛病申報errno與其相干運用辦法。本站提示廣大學習愛好者:(詳解C說話中的毛病申報errno與其相干運用辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C說話中的毛病申報errno與其相干運用辦法正文
C說話尺度庫中的毛病申報用法有三種情勢。
1、errno
errno在<errno.h>頭文件中界說,以下
#ifndef errno extern int errno; #endif
內部變量errno保留庫法式中完成界說的毛病碼,平日被界說為errno.h中以E開首的宏,
一切毛病碼都是正整數,以下例子
# define EDOM 33 /* Math argument out of domain of function. */
EDOM的意思是參數不在數學函數能接收的域中,稍後的例子頂用到了這個宏。
errno的罕見用法是在挪用庫函數之前先清零,隨後再停止檢討。
在linux中應用c說話編程時,errno是個很有效的動動。他可以把最初一次挪用c的辦法的毛病代碼保存。然則假如最初一次勝利的挪用c的辦法,errno不會轉變。是以,只要在c說話函數前往值異常時,再檢測errno。
errno會前往一個數字,每一個數字代表一個毛病類型。具體的可以檢查頭文件。/usr/include/asm/errno.h
若何把errno的數字轉換成響應的文字解釋?
一個簡略的例子
#include <stdio.h> #include <errno.h> #include <string.h> #include <math.h> int main(void) { errno = 0; int s = sqrt(-1); if (errno) { printf("errno = %d\n", errno); // errno = 33 perror("sqrt failed"); // sqrt failed: Numerical argument out of domain printf("error: %s\n", strerror(errno)); // error: Numerical argument out of domain } return 0;
2、strerror
strerror在<string.h>中界說,以下
__BEGIN_NAMESPACE_STD
/* Return a string describing the meaning of the `errno' code in ERRNUM. */
extern char *strerror (int __errnum) __THROW;
__END_NAMESPACE_STD
函數strerror前往一個毛病新聞字符串的指針,其內容是由完成界說的,字符串不克不及修正,但可以在後續挪用strerror函數是籠罩。
char *strerror(int errno)
應用方法以下:
fprintf(stderr,"error in CreateProcess %s, Process ID %d ",strerror(errno),processID)
將毛病代碼轉換為字符串毛病信息,可以將該字符串和其它的信息組合輸入到用戶界面。
注:假定processID是一個曾經獲得了的整形ID
3、perror
perror在<stdio.h>中界說,以下
__BEGIN_NAMESPACE_STD
/* Print a message describing the meaning of the value of errno.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern void perror (const char *__s);
__END_NAMESPACE_STD
函數perror在尺度毛病輸入流中打印上面的序列:參數字符串s、冒號、空格、包括errno中以後毛病碼的毛病短新聞和換行符。在尺度C說話中,假如s是NULL指針或NULL字符的指針,則只打印毛病短新聞,而不打印後面的參數字符串s、冒號及空格。
void perror(const char *s)
函數解釋
perror ( )用來將上一個函數產生毛病的緣由輸入到尺度毛病(stderr),參數s 所指的字符串會先打印出,前面再加上毛病緣由 字符串。此毛病緣由按照全局變量 errno 的值來決議要輸入的字符串。
別的其實不是一切的c函數挪用產生的毛病信息都邑修正errno。例如gethostbyname函數。
errno能否是線程平安的?
errno是支撐線程平安的,並且,普通而言,編譯器會主動包管errno的平安性。
我們看下相干頭文件 /usr/include/bits/errno.h
會看到以下內容:
# if !defined _LIBC || defined _LIBC_REENTRANT /* When using threads, errno is a per-thread value. */ # define errno (*__errno_location ()) # endif # endif /* !__ASSEMBLER__ */ #endif /* _ERRNO_H */
也就是說,在沒有界說__LIBC或許界說_LIBC_REENTRANT的時刻,errno是多線程/過程平安的。
為了檢測一下你編譯器能否界說上述變量,無妨應用上面一個簡略法式。
#include <stdio.h> #include <errno.h> int main( void ) { #ifndef __ASSEMBLER__ printf( "Undefine __ASSEMBLER__/n" ); #else printf( "define __ASSEMBLER__/n" ); #endif #ifndef __LIBC printf( "Undefine __LIBC/n" ); #else printf( "define __LIBC/n" ); #endif #ifndef _LIBC_REENTRANT printf( "Undefine _LIBC_REENTRANT/n" ); #else printf( "define _LIBC_REENTRANT/n" ); #endif return 0; }