不定参数系列printf
printf
这个最常用,作用是在屏幕上打印格式化的字符串
int printf (const char *__format, ...)
第一个参数是字符串,第二个参数是…,是不定参数,返回值是格式化后的字符串长度,其中\n\t这种转义符算一个,中文算两个长度
#include <stdio.h>
int main(void)
{
char* a="你好";
int num;
num = printf(a); // 如果是字符串直接可以把头指针放在第一参数就行
printf("上个printf长度是:%d\t",num);
return 0;
}
sprintf
这个用来格式化字符串的,格式化好的字符串返回给第一个指针
int sprintf (char *__stream, const char *__format, ...)
第一个参数是返回字符串的指针,第二个参数是格式化的,第三个是用来格式化的不定参数,返回值是字符串长度
#include <stdio.h>
int main(void)
{
char a[20];
int num = 10;
num = sprintf(a, "num的大小%d", num); // 如果是字符串直接可以把头指针放在第一参数就行
printf("上个printf长度是:%d\n格式化好的字符串是:%s",num,a);
return 0;
}
fprintf
这个用来格式化字符串输出到一个文件
int fprintf (FILE *__stream, const char *__format, ...)
第一个参数是返回文件的指针,第二个参数是格式化的,第三个是用来格式化的不定参数,返回值是格式化好的字符串的长度
#include <stdio.h>
int main()
{
FILE * fp;
fp = fopen ("file.txt", "w+");
fprintf(fp, "今天是%d", 20200510);
fclose(fp);
return(0);
}
snprintf
这个也是用来格式化字符串的,对比sprintf只是多了一个长度参数,用起来比较安全
int snprintf (char *__buf, size_t __len, const char *__format, ...)
第一个参数是返回字符串的指针,第二个是长度,第三个参数是格式化的,第四个是用来格式化的不定参数,返回值是字符串长度
#include <stdio.h>
int main()
{
char name1[6] = {'\0'};
char name2[6] = {'\0'};
int size1 = sprintf(name1, "%s", "Arthur");
printf("name1:%s, size1:%d\n", name1, size1); // 结果:name1:Arthur, size1:6
int size2 = snprintf(name2, sizeof(name2)/sizeof(char), "%s", "Arthur");
printf("name2:%s, size2:%d\n", name2, size2); // 结果:name2:Arthu, size2:6
return 0;
}
为什么说安全,这里就要说道说道,理论上很多的大学生或者大学老师在教课的时候很容易产生一个误区。就是很多的人认为设定一个字符数组去存放“Arthur”应该设置成num[6],实际上这是个错误的想法。众所周知字符串的末尾一般会有个‘\0’作为结尾,当你本来设定好的6个数组存实际上存放了七个,所以在连续的内存后还有内存被修改了,如果你哪个位置刚好是别的地方的参数,那么整个程序就会一次走向无法控制的结果。所以当我们要存一个字符串的时候一定要准备一个比字符串长度大一个的数组去存它,才不会导致越界。
上面的例子就很好的阐述了为什么snprintf比sprintf安全。
va_list 系列printf
vprintf
这个系列的函数一般是为不定参数函数服务的参数,可能实用性不是特别的强但是作为都带printf的有必要拿出来说道说道
int vprintf(const char *format, va_list arg)
这个系列函数在用的时候都要带上#include <stdarg.h>这个库文件,这个库文件里定义了va_list结构体,
还有一系列的宏定义函数等
#include <stdio.h>
#include <stdarg.h>
void WriteFrmtd(char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
int main ()
{
WriteFrmtd("%d variable argument\n", 1);
WriteFrmtd("%d variable %s\n", 2, "arguments");
return(0);
}
vsprintf
和sprintf对比来看同样也就是最后一个参数的区别
int vsprintf(char *str, const char *format, va_list arg)
#include <stdio.h>
#include <stdarg.h>
char buffer[80];
int vspfunc(char *format, ...)
{
va_list aptr;
int ret;
va_start(aptr, format);
ret = vsprintf(buffer, format, aptr);
va_end(aptr);
return(ret);
}
int main()
{
int i = 5;
float f = 27.0;
char str[50] = "hello world";
vspfunc("%d %f %s", i, f, str);
printf("%s\n", buffer);
return(0);
}
vfprintf
int vfprintf(FILE *stream, const char *format, va_list arg)
#include <stdio.h>
#include <stdarg.h>
void WriteFrmtd(FILE *stream, char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stream, format, args);
va_end(args);
}
int main ()
{
FILE *fp;
fp = fopen("file.txt","w");
WriteFrmtd(fp, "This is just one argument %d \n", 10);
fclose(fp);
return(0);
}
vsnprintf
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
#include <stdio.h>
#include <stdarg.h>
#define MAXLEN 10
int mon_log(char* format, ...)
{
char str_tmp[MAXLEN];
int i=0,j=0;
va_list vArgList;
va_start (vArgList, format);
i=vsnprintf(str_tmp, MAXLEN, format, vArgList);
va_end(vArgList);
printf("%s", str_tmp);
for(j=0;j<MAXLEN;j++)
{
printf("%d ", str_tmp[j]);
}
printf("\n");
return i;
}
void main()
{
int i=mon_log("%s,%d,%d,%c","abc",2,3,'\n');
printf("%d\n",i);
}
版权声明:本文为CSDN博主「夏虫不可与之言冰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42679566/article/details/106033378