① C語言perror函數的作用
perror ( )用 來 將 上 一 個 函 數 發 生 錯 誤 的 原 因 輸 出 到 標 准 錯誤 (stderr) 。參數 s 所指的字元串會先列印出,後面再加上錯誤原因字元串。此錯誤原因依照全局變數errno 的值來決定要輸出的字元串。
在庫函數中有個error變數,每個error值對應著以字元串表示的錯誤類型。當你調用"某些"函數出錯時,該函數已經重新設置了error的值。perror函數只是將你輸入的一些信息和現在的error所對應的錯誤一起輸出。
範例:
測試環境:linux,GCC
#include <stdio.h>
int main(void)
{
FILE *fp ;
fp = fopen( "/root/noexitfile", "r+" );
if ( NULL == fp )
{
perror("/root/noexitfile");
}
return 0;
}
運行結果:
[root@localhost io]# gcc perror.c
[root@localhost io]# ./a.out
/root/noexitfile: No such file or directory
② fopen_s函數調用不成功,input總為NULL,試過fopen函數了,代碼如下...perror提示文件路徑是無效參數
你的程序中,第十行,fopen_s(&input,"./in.txt","r");
在,"./in.txt"的第一個雙引號號和點之間,多出了一個看不見的字元,把這個不可見字元刪除,
問題就解決了。
③ 網路錯誤errorno=-99993
當linux中的C api函數發生異常時,一般會將errno變數(需include
errno.h)賦一個整數值,不同的值表示不同的含義,可以通過查看該值推測出錯的原因,在實際編程中用這一招解決了不少原本看來莫名其妙的問題。但是errno是一個數字,代表的具體含義還要到errno.h中去閱讀宏定義,而每次查閱是一件很繁瑣的事情。有下面幾種方法可以方便的得到錯誤信息
(1)void perror(const char *s)
函數說明
perror ( )用來將上一個函數發生錯誤的原因輸出到標准錯誤(stderr),參數s
所指的字元串會先列印出,後面再加上錯誤原因 字元串。此錯誤原因依照全局變數
errno 的值來決定要輸出的字元串。
(2) char *strerror(int errno)
將錯誤代碼轉換為字元串錯誤信息,可以將該字元串和其它的信息組合輸出到用戶界面例如
fprintf(stderr,"error in CreateProcess %s, Process ID %d
",strerror(errno),processID)
註:假設processID是一個已經獲取了的整形ID
(3)printf("%m", errno);
另外不是所有的地方發生錯誤的時候都可以通過error獲取錯誤代碼,例如下面的代碼段
#include"stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "netdb.h"
#include "sys/types.h"
#include "netinet/in.h"
int main (int argc, char *argv[])
{
struct hostent *h;
if (argc != 2)
{
fprintf (stderr ,"usage: getip address\n");
exit(1);
}
if((h=gethostbyname(argv[1])) == NULL)
{
herror("gethostbyname");
exit(1);
}
printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n", inet_ntoa (*((struct in_addr *)h->h_addr)));
return 0;
}
通過上面的代碼可以看到:使用gethostbyname()函數,你不能使用perror()來輸出錯誤信息(因為錯誤代碼存儲在
h_errno 中而不是errno 中。所以,你需要調用herror()函數。
你簡單的傳給gethostbyname()
一個機器名("bbs.tsinghua.e.cn"),然後就從返回的結構struct hostent
中得到了IP 等其他信息.程序中輸出IP 地址的程序需要解釋一下:h->h_addr
是一個char*,但是inet_ntoa()函數需要傳遞的是一個struct in_addr
結構。所以上面將h->h_addr 強制轉換為struct
in_addr*,然後通過它得到了所有數據。
④ 多個程序日誌重定向到同一個日誌會出錯么
#include <string.h>
char *strerror(int errnum);
此函數將errnum(通常就是errno)映射為一個出錯信息字元串,並且返回此字元串的指針。
#include <stdio.h>
void perror(const char *msg);
perror函數在標准出錯上產生一條出錯消息(基於errno的當前值),然後返回。它首先輸出msg字元串,然後「:」、空格,然後是對應於errno值的出錯信息,然後是一個新的換行符。
例示:
#include <errno.h>
#include 「ourhdr.h」 //本書的定義的頭文件
int
main(int argc, char *argv[])
{
fprintf(stderr, 「EACCES: %s /n」, strerror(EACCES));
errno = ENOENT;
perror( argv[0] );
exit(0);
}
這里,我們是人為給errno賦值,然後分別讓strerror和perror列印出錯信息。strerror是根據errno值返回出錯信息。perror是列印當前errno的值,並且可以附帶一個msg的附加信息。
重定向符號:」>」 和 」<」
1、2>out.log 將標准出錯重定向到文件out.log
2、2>&1將標准出錯信息重定向到標准輸出
3、makefile >out.log 2>&1 將標准出錯重定向到標准輸出,然後再重定向到out.file。
注意:順序不能變。從右向左。
這樣得到的文件內容與原來終端上的結果是一樣的。(終端上顯示了標准輸入/輸出/出錯等所有信息,而不僅僅是標准輸出)
4、makefile >out.log 將標准輸出重定向到out.log文件。
注意:由於要把編譯信息重定向到文件,所以把標准出錯重定向是必要的。
5、makefile 2>&1 >out.log 先把標准輸出重定向到out.log,然後再將標准出錯重定向到標准輸出,這樣out.log文件中的內容就只是標准輸出的內容。
6、makefile >out.log 2>out.log 先把標准出錯重定向到out.log,再把標准輸出重定向到out.log,這樣out.log文件中的內容順序是混亂的。
另外,UNIX環境中有一個特殊的文件/dev/null,它像一個無底洞,所有重定向到它的信息都會消失。這樣,當我們不需要回顯信息的時候,就可以將輸出重定向到/dev/null。這個就像是UNIX環境中的回收站吧。
⑤ 線程中為什麼不能用perror
perror(s) 用來將上一個函數發生錯誤的原因輸出到標准設備(stderr)。參數 s 所指的字元串會先列印出,後面再加上錯誤原因字元串。此錯誤原因依照全局變數errno(這里的說法不準確,errno是一個宏,該宏返回左值) 的值來決定要輸出的字元串。在庫函數中有個errno變數,每個errno值對應著以字元串表示的錯誤類型。當你調用"某些"函數出錯時,該函數已經重新設置了errno的值。perror函數只是將你輸入的一些信息和現在的errno所對應的錯誤一起輸出。
strerror函數是通過標准錯誤的標號,獲得錯誤的描述字元串 ,將單純的錯誤標號轉為字元串描述,方便用戶查找錯誤。
其次,了解兩函數的原型不同:
perror()原型:
#include <stdio.h>
void perror(const char *msg);
它是基於errno的當前值,在標准出錯上產生一條出錯信息,然後返回。它首先輸出由msg指向的字元串,然後是一個冒號,一個空格,接著是對應於errno值的出錯信息,最後是一個換行符。
strerror()原型:
#include <string.h>
char * strerror(int errnum);
此函數將errnum(它通常就說errno值)映射為一個出錯信息字元串,並返回此字元串的指針。
最後,兩函數的使用具體區別如下:
perror是將errno對應的錯誤消息的字元串列印到標准錯誤輸出上,即stderr或2上,若你的程序將標准錯誤輸出重定向到/dev/null,那就看不到了,就不能用perror了。而 strerror的作用只是將errno對應的錯誤消息字元串返回,要怎樣處理完全由你自己決定。通常我們選擇把錯誤消息保存到日誌文件中,即寫文件,所以通常可以用fprintf(fp, "%s", strerror(errno))將錯誤消息列印到fp指向的文件中。其中perror中errno對應的錯誤消息集合跟strerror是一樣的,也就是說不會漏掉某些錯誤。
⑥ LinuxC語言頭裡面的ERROR函數怎麼使用
errno會返回一個數字,每個數字代表一個錯誤類型。詳細的可以查看頭文件。/usr/include/asm/errno.h
如何把errno的數字轉換成相應的文字說明?
方式一:可以使用strerrno函數
char *strerror(int errno)
使用方式如下:
fprintf(stderr,"error in CreateProcess %s, Process ID %d ",strerror(errno),processID)
將錯誤代碼轉換為字元串錯誤信息,可以將該字元串和其它的信息組合輸出到用戶界面。
註:假設processID是一個已經獲取了的整形ID
方式二:使用perror函數
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;
}
⑦ c語言庫函數中有error函數嗎
c語言標准庫函數里沒有error函數。C語言對異常的處理確實不夠好,大多的時候都需要人工除錯。
有幾個類似的函數,分別處理各種情況下的異常:
ferror函數:在調用各種輸入輸出函數(如
putc.getc.fread.fwrite等)時,如果出現錯誤,除了函數返回值有所反映外,還可以用ferror函數檢查。
它的一般調用形式為
ferror(fp);如果ferror返回值為0(假),表示未出錯。如果返回一個非零值,表示出錯。應該注意,對同一個文件
每一次調用輸入輸出函數,均產生一個新的ferror函
數值,因此,應當在調用一個輸入輸出函數後立即檢
查ferror函數的值,否則信息會丟失。在執行fopen函數時,ferror函數的初始值自動置為0。在庫函數中有個errno變數,每個errno值對應著以字元串表示的錯誤類型。當你調用"某些"函數出錯時,該函數已經重新設置了errno的值。perror函數只是將你輸入的一些信息和現在的errno所對應的錯誤一起輸出。
perror函數:
用來將上一個函數發生錯誤的原因輸出到標准設備(stderr)。參數
s
所指的字元串會先列印出,後面再加上錯誤原因字元串。此錯誤原因依照全局變數errno
的值來決定要輸出的字元串。
strerror函數:用來
從錯誤號碼
查
用英文表達的錯誤內容,返回指針,指向這段英文字元串。如果你不知道錯誤號,那麼在出錯發生時,及時用
errno
的當前值
作參數,列印這段字元串。
⑧ c語言庫函數中有error函數嗎
c語言標准庫函數里沒有error函數。C語言對異常的處理確實不夠好,大多的時候都需要人工除錯。
有幾個類似的函數,分別處理各種情況下的異常:
ferror函數:在調用各種輸入輸出函數(如 putc.getc.fread.fwrite等)時,如果出現錯誤,除了函數返回值有所反映外,還可以用ferror函數檢查。 它的一般調用形式為 ferror(fp);如果ferror返回值為0(假),表示未出錯。如果返回一個非零值,表示出錯。應該注意,對同一個文件 每一次調用輸入輸出函數,均產生一個新的ferror函 數值,因此,應當在調用一個輸入輸出函數後立即檢 查ferror函數的值,否則信息會丟失。在執行fopen函數時,ferror函數的初始值自動置為0。在庫函數中有個errno變數,每個errno值對應著以字元串表示的錯誤類型。當你調用"某些"函數出錯時,該函數已經重新設置了errno的值。perror函數只是將你輸入的一些信息和現在的errno所對應的錯誤一起輸出。
perror函數: 用來將上一個函數發生錯誤的原因輸出到標准設備(stderr)。參數 s 所指的字元串會先列印出,後面再加上錯誤原因字元串。此錯誤原因依照全局變數errno 的值來決定要輸出的字元串。
strerror函數:用來 從錯誤號碼 查 用英文表達的錯誤內容,返回指針,指向這段英文字元串。如果你不知道錯誤號,那麼在出錯發生時,及時用 errno 的當前值 作參數,列印這段字元串。