stderr,strerror,errno,perror,论坛大神的回答!

摘自 http://bbs.bccn.net/thread-313805-1-1.html 的 论坛回答。

 

1:

stderr是C、C++中fprint函数的标准输出流

errno是一个在Linux C 发生异常时,系统自动赋值的全局变量,在头文件<errno.h>中,不同的值可以表示不同的意思,程序员可以通过查找对应出错误

但这显然很麻烦,所以就有了函数strerror,该函数可直接返回错误,免去了查找的过程,然后可以配合fprint函数中的stderr将错误信息输出.

 

 

2:

strerror 是把出错信息打印到指定位置 stderr 即:打印到标准出错。。 也可以选择打印到其他位置!

stdin   stdout 为标准输入输出。。

perror 输出固定为stdout.

 

stdin stdout:程序在启动时都会打开三个流,一个用于输入,一个用于输出,一个用于打印诊断或错误消息。典型的,他们被连接到用户的终端      (参见 tty(4))      但是也有可能指向文件或是其他设备,取决于父进程选择设置了什么 (参见 sh(1)      的重定向 (``Redirection'') 章节。)       输入流被称为 ``standard input''; 输出流被称为 ``standard output'';      错误流被称为 ``standard      error''。这些名词通常简写为符号,用于引用这些文件,它们是 stdin, stdout,      和 stderr.       这些符号中,每一个都是 stdio(3) 中的一个宏,类型是指向 FILE      的指针,可以用于类似 fprintf(3) 或 fread(3) 等函数中。       由于 FILE 是一个对 Unix 文件描述符加以缓冲的包装,下层的文件也可以使用-      始的 Unix 文件接口来存取。也就是,类似 read(2) 和 lseek(2) 的函数。与流      stdin, stdout, 和 stderr 关联的整数形式的文件描述符分别是 0,1 还有      2。预处理器符号 STDIN_FILENO,STDOUT_FILENO 和 STDERR_FILENO      分别以它们为值,定义在 <unistd.h> 中。       注意混合使用 FILE 和-      始的文件描述符可能带来不可预料的结果,一般应当避免。(对于喜欢追根问底的人:POSIX.1      规范的 8.2.3 节详细地描述了这样的混合使用怎样才能不出错。)      一个简单的规则是,文件描述符由内核控制,而 stdio      仅仅是一个库。它的意思是,例如当调用 exec      之后,子进程可以继承所有打开的文件描述符,但是任何杂械牧鞫疾豢稍俅嫒×恕       由于符号 stdin, stdout, 和 stderr      被指定为宏,为它们赋值将导致不可移植。利用库函数 freopen(3)      ,标准流可以用来指向不同的文件。引进这个函数专门用来为 stdin, stdout, 和      stderr 重新赋值。标准流在调用 exit(3) 和程序正常中止时被关闭。      sh(1), csh(1), open(2), fopen(3), stdio(3)

perror: 输出固定为stdout.

 

3:

楼上对那两个函数说的很詳細了。我讲点相关的东西,以便加深理解。

首先楼主得知道 fprintf 怎么用。它的第一个参数是 FILE* ,stdin stdout stderr 都是定义好了的。可以直接用。


然后就是问到的那两个错误处理函数。

perror 就是把错误号关联原因输出到 stderr。直接输出很方便,一般程序里用的比较多。
比如 perror ("fopen"); 这个语句,会输出类似:
fopen: XXXXXX
的样子。XXX 表示错误的原因。
很多库函数有返回值。在出现错误后,会返回一个特殊值,以指示错误。并祈求调用都检查。但发现错误后,通过返回值可能不能确定错误原因。因此那些库函数会再返回之前,设置 erron 这个全局变量。调用者在接到返值之后,如果发现错误发生,应该立刻核查 erron 的值,并做错误处理。
不过有些错误是致命错误,没什么可处理的办法,那么好的原则,是打印错误信息并退出程序。这时 perror 就会派上用场,它直接利用 erron 变量的值,因此好像不用传什么参数。但是究竟是在什么地方出的错误呢?如果只打一个错误会让人费解,那么前缀一些提示信息会更好一些。
比如我举的那个例子,就像是在说,执行 fopen 的时候发生了错误,错误原因是 XXXX。

为什么不直接用 erron 来表示错误呢?因为它是一个数。我说发生了错误5,谁知道是什么意思?还有,随着环境不同,同一个数也可能表示的意思不同。perror 会把它翻译成一个可读的字符串打出来。

你会发现,perror 的行为太固定,不灵活(其实一般也够用了~~)。 strerror 可能会派上点用场。它只把数翻译成串返回来,不打印。你把它放到 fprintf 里,像这样,你就可以更自由的输出些东西。另一个灵活的地方是,它是根据传的参数转换的,不是固定用的 erron。
比如你想知道你的系统把 5 定义成什么错误啦之类的问题,用 strerror 可以娱乐一下~~

 

4:

查 看错误代码errno是调试程序的一个重要方法。当linuc C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因。在实际编程中用这一招解决了不少原本看来莫名其妙的问题。比较 麻烦的是每次都要去linux源代码里面查找错误代码的含义,现在把它贴出来,以后需要查时就来这里看了。
以下来自linux 2.4.20-18的内核代码中的/usr/include/asm/errno.h
#ifndef _I386_ERRNO_H
#define _I386_ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#endif

posted @ 2017-06-04 09:17  颜小雀  阅读(746)  评论(0编辑  收藏  举报