C语言中,printf、fprintf、sprintf、snprintf、vprintf、vfprintf、vsprintf和vsnprintf的区别与用法

C语言中的printffprintfsprintfsnprintfvprintfvfprintfvsprintfvsnprintf都是用于格式化输出的函数。它们主要的区别在于输出的目的地以及是否支持可变参数列表。

1. printf

printf 用于将格式化的输出发送到标准输出(通常是控制台)。

用法:

#include <stdio.h>

int main() {
    int num = 10;
    printf("The number is %d\n", num);
    return 0;
}

2. fprintf

fprintf 用于将格式化的输出发送到指定的文件流。

用法:

#include <stdio.h>

int main() {
    int num = 10;
    FILE *fp = fopen("output.txt", "w");
    if (fp != NULL) {
        fprintf(fp, "The number is %d\n", num);
        fclose(fp);
    }
    return 0;
}

3. sprintf

sprintf 用于将格式化的输出存储在一个字符串中。

用法:

#include <stdio.h>

int main() {
    int num = 10;
    char buffer[50];
    sprintf(buffer, "The number is %d", num);
    printf("%s\n", buffer);
    return 0;
}

4. snprintf

snprintf 类似于 sprintf,但它会避免缓冲区溢出。snprintf 限制了写入字符的最大数量。

用法:

#include <stdio.h>

int main() {
    int num = 10;
    char buffer[50];
    snprintf(buffer, sizeof(buffer), "The number is %d", num);
    printf("%s\n", buffer);
    return 0;
}

5. vprintf

vprintf 用于将格式化的输出发送到标准输出,使用 va_list 类型的参数列表。

用法:

#include <stdio.h>
#include <stdarg.h>

void my_vprintf(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

int main() {
    my_vprintf("The number is %d\n", 10);
    return 0;
}

6. vfprintf

vfprintf 用于将格式化的输出发送到指定的文件流,使用 va_list 类型的参数列表。

用法:

#include <stdio.h>
#include <stdarg.h>

void my_vfprintf(FILE *file, const char *format, ...) {
    va_list args;
    va_start(args, format);
    vfprintf(file, format, args);
    va_end(args);
}

int main() {
    FILE *fp = fopen("output.txt", "w");
    if (fp != NULL) {
        my_vfprintf(fp, "The number is %d\n", 10);
        fclose(fp);
    }
    return 0;
}

7. vsprintf

vsprintf 用于将格式化的输出存储在一个字符串中,使用 va_list 类型的参数列表。

用法:

#include <stdio.h>
#include <stdarg.h>

void my_vsprintf(char *buffer, const char *format, ...) {
    va_list args;
    va_start(args, format);
    vsprintf(buffer, format, args);
    va_end(args);
}

int main() {
    char buffer[50];
    my_vsprintf(buffer, "The number is %d", 10);
    printf("%s\n", buffer);
    return 0;
}

8. vsnprintf

vsnprintf 类似于 vsprintf,但它会避免缓冲区溢出。vsnprintf 限制了写入字符的最大数量。

用法:

#include <stdio.h>
#include <stdarg.h>

void my_vsnprintf(char *buffer, size_t size, const char *format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, size, format, args);
    va_end(args);
}

int main() {
    char buffer[50];
    my_vsnprintf(buffer, sizeof(buffer), "The number is %d", 10);
    printf("%s\n", buffer);
    return 0;
}

总结

  • printf: 将格式化输出发送到标准输出(控制台)。

  • fprintf: 将格式化输出发送到指定的文件流。

  • sprintf: 将格式化输出存储在一个字符串中,不检查缓冲区溢出。

  • snprintf: 将格式化输出存储在一个字符串中,并指定最大写入字符数,以避免缓冲区溢出。

  • vprintf: 与 printf 类似,但使用 va_list 类型的参数列表。

  • vfprintf: 与 fprintf 类似,但使用 va_list 类型的参数列表。

  • vsprintf: 与 sprintf 类似,但使用 va_list 类型的参数列表。

  • vsnprintf: 与 snprintf 类似,但使用 va_list 类型的参数列表。

    综合使用sprintf、fprintf和vfprintf,创建log_printf函数,该函数实现日志打印,生成日志头部信息,包含系统时间、文件名和行号

void log_printf(const char *c_file_name, unsigned int line, const char *fmt, ...)
{

        // 定义一个字符数组用于存储打印的字符串
		char printfstr[128];
        
        // 清空字符数组,将所有元素置为0
		memset(printfstr, 0, sizeof(printfstr));

        // 格式化并生成日志头部信息,包含系统时间、文件名和行号
	  sprintf(printfstr, "[Time:%d File:%s Line:%d]", SystemTick, filename(c_file_name), line);

        // 将日志头部信息写入指定的流(串口USART1_STREAM)
	  fprintf(USART1_STREAM, "%s", printfstr);

        // 定义一个 va_list 变量,用于处理可变参数列表
	  va_list arg;

        // 初始化 va_list 变量,指向可变参数列表的第一个参数
	  va_start(arg, fmt);

        // 使用 vfprintf 将格式化的日志信息写入指定的流
	  vfprintf(USART1_STREAM, fmt, arg);

        // 结束可变参数列表的处理
	  va_end(arg);

        // 将换行符写入指定的流
	  fprintf(USART1_STREAM, "%s", "\\r\\n");
}

int main() {
			
    	log_printf(__FILE__,__LINE__,"==================APP DATE:%s \n",__DATE__); //输出编译日期
			log_printf(__FILE__,__LINE__,"==================APP TIME:%s \n",__TIME__); //输出编译时间
		
}

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值