C语言从头学66—学习头文件 <stdio.h>(二)

关于可变参数,我们曾经在《C语言从头学27》中接触过,下面学习能够接收可变参数作为

参数的几个函数。

一、printf函数的能够接收可变参数的变体函数:

1、函数vprintf()

功能:按照给定格式,将可变参数中的内容输出到控制台(显示器)

使用格式:vprintf (参1,参2);

参1:格式字符串

参2:可变参数变量(对象)

返回值:返回值输出的字符数;出错返回负值。

说明:vprintf()函数可以可以接收va_list对象作为自己的参数,而va_list对象只有在自定义可变参数函数中才能用到,因此vprintf()必须结合自定义可变参数函数才能正常使用;它通过va_list对象对可变函数中的"..."代表的内容进行处理。vprintf()函数不能像printf()那样直接使用。(具体见后边案例)

2、函数vfprintf()

功能:按照给定格式,将可变参数中的内容输出到文件

使用格式:vfprintf(参1,参2,参3);

参1:文件指针

参2:格式字符串

参3:可变参数变量(对象)

返回值:返回输出的字符数;出错返回负值。

说明:vfprintf()除了将可变参数内容写入文件不同于上一个函数外,其它方面同1的说明。

3、函数vsprintf()

功能:按照给定格式,将可变参数中的内容输出到字符串

使用格式:vsprintf();

参1:字符串指针

参2:格式字符串

参3:可变参数变量(对象)

返回值:返回输出的字符数;出错返回负值。

说明:具体参照1的说明。

二、scanf函数的能够接收可变参数的变体函数:

1、vscanf()

功能:按照格式字符串给定格式从键盘读取输入值。

使用格式:vscanf(参1, 参2);

参1:格式字符串

参2:可变参数变量(对象)

返回值:返回成功读取的项数;遇到文件结尾或发生错误返回-1。

2、vfscanf()

功能:按照格式字符串给定格式,从文件读取内容

使用格式:vfscanf(参1,参2,参3);

参1:文件指针

参2:格式字符串

参3:可变参数变量(对象)

3、vsscanf()

功能:按照格式字符串给定格式从字符串读取内容

使用格式:vsscanf(参1,参2,参3);

参1:字符串指针

参2:格式字符串

参3:可变参数变量(对象)

说明:a. 这三个函数的使用方法与前面的三个函数很相似,具体可见后边的举例程序;b. 可变参数用于存放读取到的内容,为保证退出函数时值还在参数要用引用方式。

三、举例程序

cpp 复制代码
#include<stdio.h>
#include <stdarg.h>//使用可变参数需用
int myPrintf(char* fmt, ...)
{
	va_list va; //声明一个可变参数对象
	va_start(va, fmt); //初始化可变参数对象(通过fmt定位找到"...")
	int ret = vprintf(fmt, va); //将va作为参数传入vprintf函数
	va_end(va); //注销va
	printf("\n");
	return ret; //ret不为负值表示正常显示
}
int myString(char* mystring,char* fmt, ...)
{
	va_list va;
	va_start(va, fmt);
	int ret = vsprintf(mystring, fmt, va);
	va_end(va);
	return ret;
}
int myScanf(char* string, char* fmt, ...)
{
	va_list va;
	va_start(va, fmt);
	int ret = vsscanf(string, fmt, va);
	va_end(va);
	return ret;
}
int main(void)
{
//实验函数vprintf()
	char* fmt = "字符串s:%s包含%d个字符";
	char* s = "abcdef";
	int len = strlen(s);
	int ret=myPrintf(fmt, s, len);//运行结果:字符串s:abcdef包含6个字符
	  //分析:上面的使用场景与使用printf相似,如果把上面三个参数给printf()会得到一样的结果。
	if (ret >= 0)printf("vprintf()函数调用正常,输出字符%d个\n",ret);
	       //运行结果:vprintf()函数调用正常,输出字符26个
//实验函数vsprintf()
	char ch[1024] = { 0 };
	fmt = "%s%s%s";
	char* s1 = "天津市";
	char* s2 = "南开区";
	char* s3 = "位于天津的西南部。";
	ret = myString(ch, fmt, s1, s2, s3);
    if (ret >= 0)printf("vsprintf()函数调用正常,写入字符%d个\n", ret);
	       //运行结果:vsprintf()函数调用正常,写入字符30个
	printf("%s\n", ch);//运行结果:天津市南开区位于天津的西南部。
	   //分析:myString函数将三个字符串连成一个字符串,当然也可以将数字等其他类型连成(转成)字符串。
//实验函数vsscanf()
	s1 = "abcd1234e"; //读取后字母放一起,数字放一起
	char a[1024] = { 0 };
	int b;
	ret = myScanf(s1, "%c%c%c%c%d%c", &a[0], &a[1], &a[2], &a[3], &b, &a[4]);
	printf("a=%s\n", a);//运行结果:a = abcde
	printf("b=%d\n", b);//运行结果:b = 1234
	printf("共读取项数为:%d\n", ret);//运行结果:共读取项数为:6
	getchar();
	return 0;
}
相关推荐
小僧景贤11 小时前
嵌入式C语言 第二篇:基础语法|嵌入式C与标准C的核心差异
c语言·开发语言·嵌入式c语言
wuyk55513 小时前
1.栈:后进先出的线性数据结构
c语言·数据结构·stm32·单片机
LuminousCPP14 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
带鱼吃猫15 小时前
预处理器:宏、运算符与条件编译
c语言·开发语言
(Charon)15 小时前
【C++】线程安全队列(二):生产者消费者模型与 condition_variable 阻塞等待
c语言·开发语言·c++
SunnyByte16 小时前
排序进阶:快速排序与归并排序的迭代实现,并与递归版本对比
c语言·数据结构·算法·排序算法
wuminyu17 小时前
JDK21解决虚拟线程IO阻塞原理剖析
java·linux·c语言·jvm·c++
MC皮蛋侠客20 小时前
TDengine C++ 系列(5):C/C++ 连接器——连接管理与查询 API
c语言·c++·tdengine
天空'之城20 小时前
C 语言工业级通用组件手写 27:配置参数管理组件
c语言·eeprom·参数管理·工业级组件·掉电存储
YSL07012420 小时前
指针习题讲解
c语言