C++程序中打印错误信息和标准错误流stderr

来源:互联网 发布:biz是哪个国家的域名 编辑:程序博客网 时间:2024/06/12 01:05

C++一共有三个标准流,分别是标准输入(stdin)、输出(stdout)、错误流(stderr

标准流定义和头文件

FILE *stdin; FILE *stdout; FILE *stderr; #include <stdio.h>

C++为这三个标准流分别定义了指针,stdin、stdout、stderr,它们是常量指针(因此不能被赋值),用户可以将他们作为参数用于诸如fprintf、getchar、putchar等函数中。

一般来说,stdin可以把键盘、磁盘文件以及其他外设中的数据输入内存,stdout则是把内存中的数据输出到屏幕、磁盘文件及其他外设。默认情况下,标准输入设备是键盘,而标准输出和错误流是屏幕。

打印(函数)的错误信息

调试程序的时候,经常会有打印信息到屏幕的需要,可以利用stderr和一些其他库函数做到。这里还要提到两个函数:perror、strerror,还有一个全局变量errno。

perror的定义如下:

void perror(   const char *string);

例如可以这样使用:

FILE *fp;if((fp = fopen("test.txt", "r")) == NULL)//以只读的方式打开test.txt{perror("test.txt open error");exit(0);}
如果工程目录下没有test.txt,那么输出如下:

test.txt open error: No such file or directory.


MSDN:The perror function prints an error message to stderr. 所以perror其实是将错误信息传递给stderr,由stderr打印到屏幕上的。

扩写上面的例子,来看看errno和strerror怎么用:

FILE *fp;if((fp = fopen("test.txt", "r")) == NULL){perror("test.txt open error");printf("%s\n",strerror(errno));printf("%d\n",errno);exit(0);}

output:

test.txt open error: No such file or directory
No such file or directory
2


errno是一个int型的全局变量,它(编码成错误编号)返回函数的错误信息(C/C++的库函数大都是有返回值的,以便调用者知道该函数的执行结果),例如上例的错误信息:2,所以直接打印errno对用户(编程语言的用户当然是程序员了)来说很不直观。因此C++提供了strerror函数,它可以将errno的错误翻译成对应的字符串,例如上例中的No such file or directory,这样可读性就高了很多。

strerror的定义在string.h中:

char *strerror(     int errnum);

因此如果想知道errno的各个编号分别都代表什么错误,可以将strerror的参数改成int型的数字,例如这样输出
printf("%s\n",strerror(2));

还有一个常用于输出错误的函数是fprintf,它定义在stdio.h中:

//Print formatted data to a stream.int fprintf(      FILE *stream,     const char *format [,     argument ]...  );
它的作用是将格式化的数据定向到对应的流。

例如可以这样使用:

fprintf(stderr,"error:%s\n",strerror(errno));

这样其实就是把错误信息定向到stderr标准流,再由stderr打印到屏幕(如果没有对stderr做过重定向)。



总结完打印错误信息的方法,来说说今天犯的一个很蠢的错误,因为自定义类型而出错的典型例子,结构体Vertex定义如下:

typedef struct Vertex{struct Vertex *prev, *next;double coord[3];}*VERTEX;

我在某个类的成员函数中定义并返回了一个VERTEX类型的值,函数中是这样定义的:

VERTEX v = (VERTEX)malloc(sizeof(VERTEX));

然后在main函数中也用了一个VERTEX的变量vertex接收函数的返回值,接着,就出现了错误,而且很奇怪的是F5(启动调试)不出错,CTRL+F5(运行不调试)出现了错误(程序结束运行,典型的内存使用错误),莫名其妙看了很久都没发现错误。

原因是什么呢?为VERTEX v分配空间的写法错误,上面的写法等价于(struct Vertex*)malloc(sizeof(struct Vertex*)); sizeof的变量写成了指针,这样分配的空间只是一个指针的空间大小,也就是地址长度,32位的话就是4个字节,而Vertex结构体的大小是不止4字节的,于是在将函数返回值赋值给vertex时,CTRL+F5出错,要使F5也出错很简单,去访问vertex->next和vertex->coord[i],这样就访问了未被分配的空间。正确的写法应该是:

VERTEX v = (struct Vertex*)malloc(sizeof(struct Vertex));//等价于:VERTEX v = (VERTEX)malloc(sizeof(struct Vertex));


0 0
原创粉丝点击