UNIX再学习 -- 错误和警告
来源:互联网 发布:泰国淘宝 编辑:程序博客网 时间:2024/06/16 08:50
错误和警告是常会出现的现象,了解它对以后解决问题会很有帮助。下面我们就重点来详细介绍它们。
一、错误
1、回忆错误
我们之前讲解其他内容时有涉及到错误的部分,下面让我们来回忆一下:
(1)参看:C语言再学习 -- C 预处理器
#error 字符串 => 表示产生一个错误信息
#warning 字符串 => 表示产生一个警告信息
//#error和#warning的使用 #include <stdio.h> #define VERSION 4 #define VERSION 2 #define VERSION 3 #if(VERSION < 3) #error "版本过低" #elif(VERSION > 3) #warning "版本过高" #endif int main(void) { printf("程序正常运行\n"); return 0; } 输出结果: 警告: #warning "版本过高" //错误: #error "版本过低" //程序正常运行
(2)参看:C语言再学习 -- 关键字return和exit ()函数
C语言中通过使用返回来表示是否出错,根据返回值来进行具体的错误处理一般规则:1)如果返回值类型时int类型,并且返回的值不可能是负数时,则使用返回值-1代表出错,其他数据表示正常返回。
2)如果返回值类型时int类型,并且返回的值可能是负数时,则需要使用指针取出返回值的数据,返回值仅仅表示是否出错,-1表示出错,0表示正常返回。
3)如果返回值类型是指针类型,则返回值NULL代表出错。
4)如果不考虑是否出错,返回值类型使用void即可。
(3)参看:C语言再学习 -- 文件
stderr -- 标准错误输出设备,例如:
fprintf(stderr, "Can't open it!\n");
(4)C语言再学习 -- EOF、feof函数、ferror函数
ferror () 函数用法。
2、errno 错误代码
(1)介绍errno
error 全局变量在 error.h 头文件定义,extern int errno
在文件 /usr/include/errno.h /* Declare the `errno' variable, unless it's defined as a macro by bits/errno.h. This is the case in GNU, where it is a per-thread variable. This redeclaration using the macro still works, but it will be a function declaration without a prototype and may trigger a -Wstrict-prototypes warning. */#ifndef errnoextern int errno;#endif错误 Exx 的宏定义在 /usr/include/asm-generic 文件夹下面的 errno-base.h 和 errno.h,分别定义了 1-34 、35-132 的错误定义。
查看 /usr/include/asm-generic/errno-base.h#ifndef _ASM_GENERIC_ERRNO_BASE_H#define _ASM_GENERIC_ERRNO_BASE_H#defineEPERM 1/* Operation not permitted */#defineENOENT 2/* No such file or directory */#defineESRCH 3/* No such process */#defineEINTR 4/* Interrupted system call */#defineEIO 5/* I/O error */#defineENXIO 6/* No such device or address */#defineE2BIG 7/* Argument list too long */#defineENOEXEC 8/* Exec format error */#defineEBADF 9/* Bad file number */#defineECHILD10/* No child processes */#defineEAGAIN11/* Try again */#defineENOMEM12/* Out of memory */#defineEACCES13/* Permission denied */#defineEFAULT14/* Bad address */#defineENOTBLK15/* Block device required */#defineEBUSY16/* Device or resource busy */#defineEEXIST17/* File exists */#defineEXDEV18/* Cross-device link */#defineENODEV19/* No such device */#defineENOTDIR20/* Not a directory */#defineEISDIR21/* Is a directory */#defineEINVAL22/* Invalid argument */#defineENFILE23/* File table overflow */#defineEMFILE24/* Too many open files */#defineENOTTY25/* Not a typewriter */#defineETXTBSY26/* Text file busy */#defineEFBIG27/* File too large */#defineENOSPC28/* No space left on device */#defineESPIPE29/* Illegal seek */#defineEROFS30/* Read-only file system */#defineEMLINK31/* Too many links */#defineEPIPE32/* Broken pipe */#defineEDOM33/* Math argument out of domain of func */#defineERANGE34/* Math result not representable */#endif
查看 /usr/include/asm-generic/errno.h#ifndef _ASM_GENERIC_ERRNO_H#define _ASM_GENERIC_ERRNO_H#include <asm-generic/errno-base.h>#defineEDEADLK35/* Resource deadlock would occur */#defineENAMETOOLONG36/* File name too long */#defineENOLCK37/* No record locks available */#defineENOSYS38/* Function not implemented */#defineENOTEMPTY39/* Directory not empty */#defineELOOP40/* Too many symbolic links encountered */#defineEWOULDBLOCKEAGAIN/* Operation would block */#defineENOMSG42/* No message of desired type */#defineEIDRM43/* Identifier removed */#defineECHRNG44/* Channel number out of range */#defineEL2NSYNC45/* Level 2 not synchronized */#defineEL3HLT46/* Level 3 halted */#defineEL3RST47/* Level 3 reset */#defineELNRNG48/* Link number out of range */#defineEUNATCH49/* Protocol driver not attached */#defineENOCSI50/* No CSI structure available */#defineEL2HLT51/* Level 2 halted */#defineEBADE52/* Invalid exchange */#defineEBADR53/* Invalid request descriptor */#defineEXFULL54/* Exchange full */#defineENOANO55/* No anode */#defineEBADRQC56/* Invalid request code */#defineEBADSLT57/* Invalid slot */#defineEDEADLOCKEDEADLK#defineEBFONT59/* Bad font file format */#defineENOSTR60/* Device not a stream */#defineENODATA61/* No data available */#defineETIME62/* Timer expired */#defineENOSR63/* Out of streams resources */#defineENONET64/* Machine is not on the network */#defineENOPKG65/* Package not installed */#defineEREMOTE66/* Object is remote */#defineENOLINK67/* Link has been severed */#defineEADV68/* Advertise error */#defineESRMNT69/* Srmount error */#defineECOMM70/* Communication error on send */#defineEPROTO71/* Protocol error */#defineEMULTIHOP72/* Multihop attempted */#defineEDOTDOT73/* RFS specific error */#defineEBADMSG74/* Not a data message */#defineEOVERFLOW75/* Value too large for defined data type */#defineENOTUNIQ76/* Name not unique on network */#defineEBADFD77/* File descriptor in bad state */#defineEREMCHG78/* Remote address changed */#defineELIBACC79/* Can not access a needed shared library */#defineELIBBAD80/* Accessing a corrupted shared library */#defineELIBSCN81/* .lib section in a.out corrupted */#defineELIBMAX82/* Attempting to link in too many shared libraries */#defineELIBEXEC83/* Cannot exec a shared library directly */#defineEILSEQ84/* Illegal byte sequence */#defineERESTART85/* Interrupted system call should be restarted */#defineESTRPIPE86/* Streams pipe error */#defineEUSERS87/* Too many users */#defineENOTSOCK88/* Socket operation on non-socket */#defineEDESTADDRREQ89/* Destination address required */#defineEMSGSIZE90/* Message too long */#defineEPROTOTYPE91/* Protocol wrong type for socket */#defineENOPROTOOPT92/* Protocol not available */#defineEPROTONOSUPPORT93/* Protocol not supported */#defineESOCKTNOSUPPORT94/* Socket type not supported */#defineEOPNOTSUPP95/* Operation not supported on transport endpoint */#defineEPFNOSUPPORT96/* Protocol family not supported */#defineEAFNOSUPPORT97/* Address family not supported by protocol */#defineEADDRINUSE98/* Address already in use */#defineEADDRNOTAVAIL99/* Cannot assign requested address */#defineENETDOWN100/* Network is down */#defineENETUNREACH101/* Network is unreachable */#defineENETRESET102/* Network dropped connection because of reset */#defineECONNABORTED103/* Software caused connection abort */#defineECONNRESET104/* Connection reset by peer */#defineENOBUFS105/* No buffer space available */#defineEISCONN106/* Transport endpoint is already connected */#defineENOTCONN107/* Transport endpoint is not connected */#defineESHUTDOWN108/* Cannot send after transport endpoint shutdown */#defineETOOMANYREFS109/* Too many references: cannot splice */#defineETIMEDOUT110/* Connection timed out */#defineECONNREFUSED111/* Connection refused */#defineEHOSTDOWN112/* Host is down */#defineEHOSTUNREACH113/* No route to host */#defineEALREADY114/* Operation already in progress */#defineEINPROGRESS115/* Operation now in progress */#defineESTALE116/* Stale NFS file handle */#defineEUCLEAN117/* Structure needs cleaning */#defineENOTNAM118/* Not a XENIX named type file */#defineENAVAIL119/* No XENIX semaphores available */#defineEISNAM120/* Is a named type file */#defineEREMOTEIO121/* Remote I/O error */#defineEDQUOT122/* Quota exceeded */#defineENOMEDIUM123/* No medium found */#defineEMEDIUMTYPE124/* Wrong medium type */#defineECANCELED125/* Operation Canceled */#defineENOKEY126/* Required key not available */#defineEKEYEXPIRED127/* Key has expired */#defineEKEYREVOKED128/* Key has been revoked */#defineEKEYREJECTED129/* Key was rejected by service *//* for robust mutexes */#defineEOWNERDEAD130/* Owner died */#defineENOTRECOVERABLE131/* State not recoverable */#define ERFKILL132/* Operation not possible due to RF-kill */#define EHWPOISON133/* Memory page has hardware error */#endif还有一些更大的错误号是留给内核级别的,如系统调用等,用户程序一般是看不见的这些号的,Ubuntu12.04中/usr/src/linux-headers-3.2.0-23-generic-pae/include/linux/errno.h
查看 /usr/src/linux-headers-3.2.0-23-generic-pae/include/linux/errno.h #ifndef _LINUX_ERRNO_H#define _LINUX_ERRNO_H#include <asm/errno.h>#ifdef __KERNEL__/* * These should never be seen by user programs. To return one of ERESTART* * codes, signal_pending() MUST be set. Note that ptrace can observe these * at syscall exit tracing, but they will never be left for the debugged user * process to see. */#define ERESTARTSYS512#define ERESTARTNOINTR513#define ERESTARTNOHAND514/* restart if no handler.. */#define ENOIOCTLCMD515/* No ioctl command */#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall *//* Defined for the NFSv3 protocol */#define EBADHANDLE521/* Illegal NFS file handle */#define ENOTSYNC522/* Update synchronization mismatch */#define EBADCOOKIE523/* Cookie is stale */#define ENOTSUPP524/* Operation is not supported */#define ETOOSMALL525/* Buffer or request is too small */#define ESERVERFAULT526/* An untranslatable error occurred */#define EBADTYPE527/* Type not supported by server */#define EJUKEBOX528/* Request initiated, but will not complete before timeout */#define EIOCBQUEUED529/* iocb queued, will get completion event */#define EIOCBRETRY530/* iocb queued, will trigger a retry */#endif#endif
(2)errno 转换成 字符串
1)strerror 函数
char *strerror(int errnum);
主要用于将参数指定的错误编号翻译成对应的错误信息返回。
#include <stdio.h>#include <errno.h>#include <string.h>extern int errno ;int main (){ FILE *fp; // file.txt 不存在 fp = fopen("file.txt", "r"); if( fp == NULL ) { fprintf(stderr, "错误码: %d\n", errno); fprintf(stderr, "对应错误信息为: %s\n", strerror(errno)); } else { fclose(fp); } return(0);}输出结果:错误码: 2对应错误信息为: No such file or directory
2)perror 函数 (重点)
void perror(const char *s);
函数功能:
#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>extern int errno ;int main (void){FILE *fp;// file.txt 不存在fp = fopen("file.txt", "r"); if( fp == NULL ) { printf("错误码 = %d\n",errno); perror ("打开失败"), exit (-1); } else { fclose(fp); } return(0);}输出结果:错误码 = 2打开失败: No such file or directory
3)printf 函数
#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>extern int errno ;int main (void){FILE *fp;// file.txt 不存在fp = fopen("file.txt", "r"); if( fp == NULL ) { printf("错误码 = %d\n",errno); printf ("%m\n"); } else { fclose(fp); } return(0);}输出结果:错误码 = 2No such file or directory
(3)不能根据错误号判断是否出错
#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>extern int errno ;int main (){ FILE *fp; // file.txt 不存在 fp = fopen("file.txt", "r"); FILE *fp_test; // test.txt 存在 fp_test = fopen("test.txt", "r"); if(errno) //不能根据 errno 判断是否出错 { fprintf (stderr, "打开失败\n"); } else { fclose(fp_test); } return(0);}输出结果:打开失败
#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>extern int errno ;int main (){ FILE *fp; // file.txt 不存在 fp = fopen("file.txt", "r"); errno = 0; //将 errno 清零 FILE *fp_test; // test.txt 存在 fp_test = fopen("test.txt", "r"); if(errno) //不能根据 errno 判断是否出错 { fprintf (stderr, "打开失败\n"); } else { fclose(fp_test); } return(0);}
#include <stdio.h>#include <errno.h>#include <string.h>extern int errno ;int main (){ FILE *fp; // file.txt 不存在 fp = fopen("file.txt", "r"); if( fp == NULL ) { fprintf(stderr, "错误码: %d\n", errno); fprintf(stderr, "对应错误信息为: %s\n", strerror(errno)); } else { fclose(fp); } return(0);}输出结果:错误码: 2对应错误信息为: No such file or directory
二、编译错误和警告
1、上面提到的 errno 是标准库函数的错误代码,现在来看看gcc编译错误和警告
(1)让所有编译警告都显示出来,选项 -Wall
如下,编辑一段警告的代码#include <stdio.h> int main (void) { int i; printf ("\n hello world![i]\n", i); return 0; } root@ubuntu:/home/tarena/project/c_test# gcc -Wall hello.c -o hello hello.c: 在函数‘main’中: hello.c:6:2: 警告: 提供给格式字符串的实参太多 [-Wformat-extra-args] hello.c:6:9: 警告: 此函数中的‘i’在使用前未初始化 [-Wuninitialized]
(2)将编译警告转换成错误的选项 -Werror
编译警告很多时候会被我们忽视,在特殊场合我们还是需要重视编译警告的,如果能把编译警告变成直接输出错误,那我们的重视程度会提高很多并去解决。#include <stdio.h> int main (void) { int i; printf ("\n hello world![i]\n", i); return 0; } root@ubuntu:/home/tarena/project/c_test# gcc -Wall -Werror hello.c hello.c: 在函数‘main’中: hello.c:6:2: 错误: 提供给格式字符串的实参太多 [-Werror=format-extra-args] cc1: all warnings being treated as errors
(3)警告级别
2、C语言编译错误及警告对照表
3、将警告,错误等信息输出到文件中
(1)其中标准输出、标准输出、标准错误,可参看:C语言再学习 -- 文件
C 程序自动打开3个文件。这3个文件被称为标准输入,标准输出和标准错误输出。默认的标准输入是系统的一般输入设备,通常为键盘;默认的标准输出和标准错误输出是系统的一般输出设备,通常为显示器,分别得到文件描述符 0, 1, 2.
下面的方法从标准输入(键盘)获得一个字符: ch = getchar ( );
标准文件指针:
stdio.h文件把3个文件指针与3个C 程序自动打开的标准文件进行了并联,如下表所示:
标准文件
文件指针
一般使用的设备
标准输入
stdin
键盘
标准输出
stdout
显示器
标准错误
stderr
显示器
这些指针都是FILE指针类型,所以可以被用作标准I/O函数的参数。
(2)下面以make命令为例来说明,如何把对应的信息,输出到对应的文件中:
【用法】1)想要把make输出的全部信息,输出到某个文件中,最常见的办法就是:
make xxx > build_output.txt
此时默认情况是没有改变2=stderr的输出方式,还是屏幕,所以,如果有错误信息,还是可以在屏幕上看到的。
2)只需要把make输出中的错误(及警告)信息输出到文件中ing,可以用:
make xxx 2> build_output.txt
相应地,由于1=stdout没有变,还是屏幕,所以,那些命令执行时候输出的正常信息,还是会输出到屏幕上,你还是可以在屏幕上看到的。
3)只需要把make输出中的正常(非错误,非警告)的信息输出到文件中,可以用:
make xxx 1> build_output.txt
相应地,由于2=stderr没有变,还是屏幕,所以,那些命令执行时候输出的错误信息,还是会输出到屏幕上,你还是可以在屏幕上看到的。
4)想要把正常输出信息和错误信息输出到分别的文件中,可以用:
make xxx 1> build_output_normal.txt 2>build_output_error.txt
即联合使用了1和2,正常信息和错误信息,都输出到对应文件中了。
5)所有的信息都输出到同一个文件中:
make xxx > build_output_all.txt 2>&1
其中的2>&1表示错误信息输出到&1中,而&1,指的是前面的那个文件:build_output_all.txt 。
注意:上面所有的1,2等数字,后面紧跟着大于号'>' ,中间不能有空格。
- UNIX再学习 -- 错误和警告
- iOS错误和警告
- vs2013 错误和警告
- Logback学习笔记 - 自动打印警告和错误消息
- 连接错误和警告处理
- Quartus常见警告和错误
- gcc警告和错误选项
- IOS之警告和错误
- ANSYS常见错误和警告
- c++警告和错误汇总
- verilog警告和错误汇总
- Xcode常见警告和错误
- 编译器警告和错误详解
- CrystalReport错误消息和公式编译器警告
- keil MDK编译器警告和错误详解
- C#的错误和警告信息指令
- XCode编译警告和错误解决方法集锦
- Xcode编译错误和警告汇总
- jdk环境变量配置及作用
- Android笔记:webView与HTML5交互方法总结
- stm32f103 c8t6 can
- iOS 高性能定时器解决方案2(商品打折倒计时)
- Linux关闭和打开图形化界面
- UNIX再学习 -- 错误和警告
- 动态规划-最短编辑距离变形----DNA对比问题
- Spring事务的隔离级别
- iOS学习笔记-060.图形的基本绘制、图片水印、图片裁剪
- 屌炸天的内核来袭,史上最小chromium内核miniblink!
- 01.Mybatis初级使用-初体验
- 位运算总结
- c++中capacity和size的区别,以及reserve和resize的区别,shink_to_fit用法
- ams启动activity过程,Binder通信,IPC机制,service内部流程,事件在activity流转分发