C程序设计语言之第7章 输入与输出

C程序设计语言之第7章 输入与输出

  • 1、标准输入/输出
  • 2、格式化输出——printf函数
  • 3、变长参数表
  • 4、格式化输入——scanf函数
  • 5、文件访问
  • 6、错误处理——stderr和exit
  • 7、行输入和行输出
  • 8、其它函数

1、标准输入/输出

介绍了重定向运算符‘<’,可以把键盘输入替换为文件输入。简单的例子可以看https://blog.csdn.net/xuan_liu123/article/details/62044623。同时也有‘>’可以讲程序输出从标准输出设备重定向到文件中。

2、格式化输出——printf函数

可以参考:https://blog.csdn.net/k346k346/article/details/52252626
函数原型为

int printf(char *format,  ...);

返回值为打印的字符数。
转换说明,或者格式控制字符串的组成为

%[flags][width][.prec][length]type
即
%[标志][最小宽度][.精度][类型长度]类型
其中[]内的内容都是可选的

转换说明都由一个百分号字符%开始,并以一个转换字符(应该就是上面说的类型)结束。大部分内容不必详说,可以看书上给的一个示例:
C程序设计语言之第7章 输入与输出_第1张图片
书上有这样一句话:

printf(s); /* FAILS if s contains % */

然后我试了一下:

#include

int main()
{
	char *str = "kdjfk%%%%qdf";
	printf(str);
	return 0;
}

得到的输出是:
在这里插入图片描述
所以这里FAILS的意思是不能输出正常的原始字符串吗?
最后介绍了:

int sprintf(char *string, char *format, arg1, arg2, ...); //将输出结果放到string中

3、变长参数表

printf声明中省略号表示参数表中参数的数量和类型是可变的。省略号只能出现在参数表的尾部。书中为了实现一个printf的最简单版本minprintf,使用了标准头文件中包含的一组宏定义(一个变量类型和三个宏)。
给出书中的描述,然后也可以看https://blog.csdn.net/holandstone/article/details/6947119。
C程序设计语言之第7章 输入与输出_第2张图片

#include 
/* minprintf: minimal printf with variable argument list */
void minprintf(char *fmt, ...)
{
	va_list ap; /* points to each unnamed arg in turn */
 	char *p, *sval;
	int ival;
	double dval;
	va_start(ap, fmt); /* make ap point to 1st unnamed arg */
	for (p = fmt; *p; p++) {
		if (*p != '%') {
			putchar(*p);
			continue;
		}
		switch (*++p) {
		case 'd':
			ival = va_arg(ap, int);
			printf("%d", ival);
			break;
		case 'f':
			dval = va_arg(ap, double);
			printf("%f", dval);
			break;
		case 's':
			for (sval = va_arg(ap, char *); *sval; sval++)
				putchar(*sval);
			break;
		default:
			putchar(*p);
			break;
		}
	}
	va_end(ap); /* clean up when done */
}

4、格式化输入——scanf函数

可以参考https://www.oschina.net/question/234345_43611。

int scanf(char *format, ...)//后面的参数必须为指针

返回值为成功匹配并赋值的输入项的个数。

//按照规定格式扫描string,并把结果分别保存到后面的参数(必须是指针)中。
int sscanf(char *string, char *format, arg1, arg2, ...) 

转换说明中使用到的星号有点特殊:“格式串种可能包含转换说明,依次由一个%、一个可选的赋值禁止字符*、一个可选的数值(指定最大字段宽度)、一个可选的h、l或者L字符(指定目标对象的宽度)以及一个转换字符组成。”
如果转换说明中有*,则跳过该输入字段,不进行赋值。输入字段定义为一个不包括空白符(包括空格、横向制表、换行、回车、纵向制表以及换页)的字符串,其边界定义为到下一个空白符或到达指定的字段宽度。

5、文件访问

FILE是一个包含文件信息的结构,包括:缓冲区的位置、缓冲区中当前字符的位置、文件的读或写状态、是否出错或是否已经到达文件结尾等等。
关于C输入输出流:
C程序设计语言之第7章 输入与输出_第3张图片
以及缓冲机制等等,都值得深入了解。

6、错误处理——stderr和exit

stderr就是操作系统开启的一个输出流,stdin和stdout可以重定向到文件,而stderr通常显示在屏幕上。书上举例:

if ((fp = fopen(*++argv, "r")) == NULL) {
	fprintf(stderr, "%s: can't open %s\n", prog, *argv);
	exit(1);
 }

书上在这一节提到了exit和return的区别,其中说到:“在主程序main中,语句 return expr 等价于 exit(expr) 。”在网上看了一下大致区别https://www.cnblogs.com/noble/p/4144166.html:

  1. return是语言级别的,它表示了调用堆栈的返回。return用于结束一个函数的运行,将函数的运行信息传出给它的调用函数使用,
  2. exit是系统调用级别的,它表示了一个进程的结束。exit函数是退出应用程序,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关,通常是0为正常退出。非0为非正常退出。
    所以说这种等价是在main函数中才会有的,因为main函数结束时也会隐式地调用exit函数
    书上说exit的优点在于“它可以从其它函数中调用”。?

7、行输入和行输出

在这里插入图片描述

8、其它函数

你可能感兴趣的:(C程序设计语言)