unix环境高级编程中的err_quit,err_sys

环境

os CentOS release 6.7 (Final)

gcc 4.4.7

c语言预备知识

标准输入输出文件

在linux系统中一切设备皆文件.文件在C语言中用指针来标识.C语言定义的3个标准文件如下所示

标准文件 文件指针 对应设备
标准输入 stdin 键盘
标准输出 stdout 显示器
标准错误 stderr 显示器

下面看2个与标准输入输出有关的函数

  • char *gets(char *s) 从标准输入stdin中读取一行到s指向的缓冲区,当遇到行结束符或者EOF时读取结束.
  • int puts(const char *s) 把s和换行符写入stdout

    看下面的代码
#include <stdio.h>
#include <string.h>
int main( ) {
char str[100];
printf( "Enter a value :");
gets(str);
printf("%zu", strlen(str)); // %zu用于输出size_t,str不包括最后的回车,所以输入abc回车,这里输出为3
printf( "\nYou entered: ");
puts(str); //当输入为abc时,这里不但输出abc还多输入一个回车.
printf("aaa");
return 0;
}

再看另外一组与标准输入输出有关的函数:

  • int scanf(const char *format, ...) 从标准输入stdin中按读取内容,
  • int printf(const char *format, ...) 把内容按format指定的格式写入准备输出

flush

看下面的代码

#include <stdio.h>
#include <string.h>
#include <unistd.h> int main() {
char buff[1024];
memset(buff, '\0', sizeof(buff)); fprintf(stdout, "Going to set full buffering on\n");
setvbuf(stdout, buff, _IOFBF, 1024); fprintf(stdout, "This is tutorialspoint.com\n");
fprintf(stdout, "This output will go into buff\n");
fflush(stdout); fprintf(stdout, "and this will appear when programm\n");
fprintf(stdout, "will come after sleeping 5 seconds\n"); sleep(5); return(0);
}

setvbuf的作用是当缓冲区buff满的时候才会写出到输出流.一直到fprintf(stdout, "This output will go into buff\n");这句话缓冲区还没有满,如果程序没有结束或者没有fflush,在显示器上可能看不到前3句的输了(或者输出不完整).调用fflush则一定能看到前3句完整的输出.最后2句话后面没有fflush函数,则不会立刻看到输出.当sleep(5)结束的时候,就能看到最后2句话输出了.

函数变长参数问题

当传入参数个数不确定时可以用变长参数.不确定的参数用...表示.最常用的变长参数函数应该就是scanf和printf了.获取变长参数的参要用到C语言定义的宏,va_start,va_arg,and va_end.这些宏在头文件stdarg.h中定义.va_start初始化变长参数的列表,va_arg在变长参数的列表中区获取下一个参数,va_end清空变长参数的列表.看下面的代码如何求和

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define END -1
int va_sum (int first_num, ...) {
va_list ap;
va_start(ap, first_num); //first_num后面的参数是变长参数
int result = first_num;
int temp = 0;
while ((temp = va_arg(ap, int)) != END) {
result += temp;
}
va_end(ap);
return result;
}
int main () {
int sum_val = va_sum(1, 2, 3, 4, 5, END);
printf ("%d", sum_val);
return 0;
}

再看一个求平均值的代码:

#include <stdarg.h>
#include <stdio.h> double average (int num, ...) {
va_list arguments;
double sum = 0;
va_start(arguments, num); //num后面的参数是变长参数
for (int x = 0; x < num; x++ ) {
sum += va_arg(arguments, double);
}
va_end(arguments);
return sum / num;
} int main() {
printf("%f\n", average(3, 12.2, 22.3, 4.5));
printf("%f\n", average(5, 3.3, 2.2, 1.1, 5.5, 3.3));
}

vsnprintf

int vsnprintf (char * s, size_t n, const char * format, va_list arg )

把va_list以格式format写到s中,前n位是有效的.

  • s 至少要n个字符,否则会有不可遇知的错误.
  • n 指定s的前n位置是有效的,后面的会被忽略.注意指定n时只能看到n-1个字符.最后一位是null
  • format 格式
  • 变长的参数列表

    看下面的例子:
#include <stdarg.h>
#include <stdio.h>
void vout(char *string, char *fmt, ...);
char fmt1 [] = "%s %s %s %s";
int main() {
char buf[100];
vout(buf, fmt1, "Sat", "Sun", "Mon", "aaa");
printf("The string is:%s\n", buf);
return 0;
}
void vout(char *buf, char *fmt, ...) {
va_list arg_ptr;
va_start(arg_ptr, fmt); //让arg_ptr指向变长参数
int n = vsnprintf(buf, 16, fmt, arg_ptr); //变长参数以fmt格式放到buf中,返回写入buf的字节数,但是只有前12个字节会输出.
printf("n=%d\n", n);
va_end(arg_ptr);
}

再看一个例子

#include <stdio.h>
#include <stdarg.h>
int mon_log(char* format, ...) {
char str_tmp[50];
int i=0;
va_list vArgList;
va_start(vArgList, format);
i = vsnprintf(str_tmp, 50, format, vArgList);
printf("%s\n", str_tmp);
va_end(vArgList);
return i;
}
int main() {
int i=mon_log("%s,%d,%d,%d","asd",2, 3, 4);
printf("%d\n", i);
return 0;
}

再看一个例子

#include <stdarg.h>
#include <stdio.h>
void vout(char *string, char *fmt, ...);
char fmt1 [] = "%s %s %s %s";
int main() {
char buf[100];
vout(buf, fmt1, "Sat", "Sun", "Mon", "aaa");
printf("The string is:%s\n", buf);
return 0;
}
void vout(char *buf, char *fmt, ...) {
va_list arg_ptr;
va_start(arg_ptr, fmt); //让arg_ptr指向变长参数
int n = vsnprintf(buf, 16, fmt, arg_ptr); //变长参数以fmt格式放到buf中,返回写入buf的字节数,但是只有前12个字节会输出.
printf("n=%d\n", n);
va_end(arg_ptr);
}

snprintf

int snprintf(char * s, size_t n, const char * format, ... );

和vsnprintf的作用差不多.不同是vsnprintf最后一个参数类型是va_list,这里是不定长参数.

看下面代码

#include <stdio.h>
int main() {
char str[10];
int ret = snprintf(str, 5, "%s", "12345678");
printf("%d\n",ret);
printf("%s\n",str);
return 0;
}

参考资料

最新文章

  1. Buffer cache hit ratio性能计数器真的可以作为内存瓶颈的判断指标吗?
  2. &lt;把时间当做朋友&gt;读书笔记
  3. IO同步、异步与阻塞、非阻塞
  4. 7.1SportsStore:Navigation and Checkout
  5. mysql,多对多的hibernate操作对应的jdbc操作
  6. 超简单fedora20(linux)下JDK1.8的安装
  7. ThreadPoolExecutor介绍
  8. Walle 瓦力 web部署系统
  9. Chrome开发者工具详解(1):Elements、Console、Sources面板
  10. django之uWSGI配置 +Nginx
  11. C#利用委托跨线程更新UI数据
  12. Oracle11G 在线重定义
  13. ASE加密
  14. node-glob的*匹配
  15. layui---表单验证
  16. java构造函数总结
  17. Java设计模式从精通到入门三 策略模式
  18. 11:vue-cli脚手架
  19. [转]【mysql监控】查看mysql库大小,表大小,索引大小
  20. 又一国产855旗舰突然现身:支持5G

热门文章

  1. 【idea】高德地图可以关爱一下高个汽车
  2. diff算法
  3. Java枚举——枚举的作用、使用方法、使用场景
  4. Python3.7.1学习(二)使用schedule模块定时执行任务
  5. django 中 css文件的调用
  6. php使用cUrl方法 get、post请求
  7. 官网例子,mt-field password获取不到
  8. JavaScript笔记八
  9. Spring security (一)架构框架-Component、Service、Filter分析
  10. csrf与xss