C语⾔流输⼊和输出函数
printf(scanf)、puts(gets)和putchar(getchar)是分别向标准流输出(由标准流读⼊)字符串、⼀⾏字符和单个字符的函数。除了这些函数,C语⾔也提供了⾯向任何流的输⼊和输出函数。
fprintf函数
fprintf函数的原型为:
int fprintf(FILE *stream, const char *format, ...);
该函数向stream流输出字符串。与printf函数唯⼀的不同只是增加了⼀个参数:访问输出流的⽂件指针,⽀持向任何流输出字符串。
可变长度实参
在<stdarg.h>中提供了三个宏va_start, va_arg和va_end以及⼀个类型va_list。利⽤这些元素可以编写具有变长参数列表的函数。
具有变长参数列表的函数必须⾄少具有⼀个正常的形式参数,在最后⼀个正常形式参数的后边添加,...。变长参数列表的声明形式为:
返回值类型函数名(正常形式参数1,正常形式参数2,...);
在函数的定义中,⾸先使⽤va_list声明变量,以⽀持访问在最后⼀个正常实际参数后⾯的实际参数:
va_list ap;
然后调⽤va_start声明可变长度部分开始的位置:
va_start(ap, 最后⼀个正常形式参数名);
之后依次通过va_arg获取可变参数:
可变参数的值 = va_arg(ap, 可变参数的类型);
在访问完成后,使⽤va_end结束:
va_end(ap);
在调⽤时,会进⾏默认的参数类型提升,例如由字符型⾃动提升到整型,由float型到double型等。
putchar函数vfprintf函数
vfprintf原型为:
int vfprintf(FILE *stream, const char *format, va_list arg);
可以在带有变长参数列表的函数内调⽤,⽀持对输出信息的包装。
/****************************************
* stream_fprintf.c                    *
*                                      *
* C语⾔中⽂件流的输出和变长参数列表函数*
****************************************/
#include <stdio.h>
flexibility作品#include <stdarg.h>
js加密库#include <stdlib.h>
void Print(FILE* fp, char *msgtype, char* format, ...)
{
va_list vp;
va_start(vp, format);
fprintf(fp, "%s: ", msgtype);
vfprintf(fp, format, vp);
va_end(vp);
fprintf(fp,"\n");
}
int Sum(size_t n, ...)
{
va_list vp;
va_start(vp, n);
size_t i = 0;
int sum = 0;
while (i < n)
{
int num = va_arg(vp, int);
sum += num;
i++;
}
va_end(vp);
return sum;逗号表达式没有括号
}
int main()
{
FILE *fp = NULL;
fp = fopen("", "w");
int n;
Print(fp, "询问","输⼊整数的个数: ");
scanf("%d", &n);
Print(fp, "询问", "输⼊%d个整数: ", n);
int *nums = malloc(n * sizeof(int));
int i = 0;
for (; i < n; i++)
{
scanf("%d", nums + i);
}
Print(fp, "结果", "输⼊的整数为:");
for (i = 0; i < n; i++)
{
fprintf(fp, "%d ", nums[i]);
}
fprintf(fp, "\n");
int sum1 = Sum(3, 4, 5, 6);
Print(fp, "结果","4,5,6的和为%d", sum1);
int sum2 = Sum(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);  Print(fp, "结果","1到10的和为%d", sum2);
fclose(fp);
return0;
}
fscanf函数
fscanf函数的原型为:
int fscanf(FILE *stream, const char *format, ...);
该函数从stream流读⼊数据。与scanf函数唯⼀的不同只是增加了⼀个参数:访问输⼊流的⽂件指针,⽀持由任何流读⼊数据。
⽂件结尾或错误指⽰函数
每个流都有两个指⽰器:错误指⽰器和⽂件末尾指⽰器。当遇到⽂件结尾时设置⽂件末尾指⽰器,若遇到错误(不是匹配错误引起的)则设置错误指⽰器。重新打开同⼀个流时会清除原来的指⽰器。也可以使⽤clearerr函数主动清除⽂件末尾指⽰器和错误指⽰器,其使⽤原型为:
void clearerr(FILE *fp);
可以利⽤feof函数检查指定的流是否设置了⽂件末尾指⽰器,如果设置了则返回⾮零值,否则返回0。feof函数的原型为:
int feof(FILE *fp);
可以利⽤ferror函数检查指定的流是否设置了错误指⽰器,设置了则返回⾮零值,否则返回0。
/**************************************
* string_scanf.c                    *
*                                    *
* C语⾔中⽂件流的输⼊和错误检测      *
**************************************/
#include <stdio.h>
int main()
{
FILE *fp = NULL;
fp = fopen("", "r");
int x ,y;
int num = fscanf(fp, "%d%d", &x, &y);
if (num < 2)
{
printf("是否已达到⽂件末尾:%d\n", feof(fp));
printf("是否出现错误: %d\n", ferror(fp));
}
clearerr(fp);
fclose(fp);
return0;
}
字符输出函数fputc和putc
putchar函数向标准输出流输出⼀个字符。fputc和putc是putchar的更通⽤版本,向任何流输出字符,两个函数的原型为:
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);
其中putc和fputc的功能相同,只是putc是利⽤宏实现的。
正常的情况下三个函数都会返回输出的字符,⽽在出现错误时都会设置错误指⽰器,并返回EOF。
字符输⼊函数fgetc、getc和ungetc
getchar从标准流中读⼊⼀个字符,fgetc和getc是getchar的更通⽤版本,从任何流读⼊⼀个字符,两个函数原型为:
int fgetc(FILE *stream);
int getc(FILE *stream);
其中getc和fgetc的功能相同,但getc是利⽤宏实现的。
fgetc、getc和getchar三个函数在与遇到⽂件结尾的问题,都会设置⽂件末尾指⽰器,并返回EOF。如果产⽣了错误,就会设置错误指⽰器。
gets函数头文件c用不了ungetc函数将从流中读⼊的字符回退,并清除掉流的⽂件末尾指⽰器,原型为:
int ungetc(int c, FILE *stream);
通过多次调⽤ungetc函数可以回退多个的字符,可以回退的数量依赖于实现和流的类型。调⽤⽂件定位函数会丢失回退的字符。ungetc正常情况下会返回字符,若试图返回过多的字符则返回EOF。
/**************************************
* stream_char.c                      *
*                                    *
* C语⾔⽂件流输⼊和输出字符          *
**************************************/
#include <stdio.h>
int main()
{
FILE *fp = NULL;
fp = fopen("", "w+");
int c = 'A';
fputc(c, fp);
c = 'B';
fputc(c, fp);
c = 'C';
fputc(c, fp);
/
*将⽂件位置返回到开头*/
rewind(fp);
c = fgetc(fp);
printf("读出字符:%c\n", c);
c = fgetc(fp);
printf("读出字符:%c\n", c);
ungetc(c,fp);
printf("放回字符:%c\n", c);
c = fgetc(fp);
printf("再次读出字符:%c\n", c);
fclose(fp);
return0;
ios widget开发
}
⾏输出函数fputs
puts函数向标准输出流stdout输出⼀串字符,并且在输出字符后⾃动添加⼀个换⾏符。fputs是puts的更通⽤版本,可以向任意的输出流写⼊字符串,不同的是它不会⾃动添加换⾏符。fputs的函数原型为:
int fputs(const char *s, FILE *stream);
当出现错误时,两个函数都返回EOF。否则,返回⼀个⾮负数。
⾏输⼊函数fgets
gets函数向标准输出流stdin读⼊⼀串字符,逐个读⼊字符,在遇到换⾏符时停⽌,并⾃动丢弃换⾏符。fgets是gets的更通⽤版本,可以从任意的输出流读⼊字符串,也更安全,限制了读⼊的字符的数
量。fgets的函数原型为:
char *fgets(char *s, int n, FILE *stream);
fgets函数逐个读⼊字符,并在遇到⾸个换⾏符时停⽌操作,或者已读到n-1个字符时停⽌操作,且fgets会将换⾏符和其他字符⼀起存储。如果在读⼊过程中发⽣错误或者在读⼊任何字符前达到了输⼊流的末尾,则返回空指针,否则都返回读⼊字符串的指针。