c语言printf大家族系列

不定参数系列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] = {0}; // 给予过量的空间来存放字符串
    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);
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值