C语言的标准库实现了简单地文本输入和输出,文本流由一系列行组成,行的结尾是换行符,如果该系统并没有遵循这种模式,则标准库将通过一系列措施使得该系统适应这种模式,例如标准库可以在输入端将回车符和换页符都转换为换行符,而在输出端进行反向转换。
一、getchar
int getchar(void);
这是最简单的输入函数,他可以从命令行一次读取一个字符,如果遇到文件结尾则返回EOF,EOF一般在 stdio.h 中被定义为-1。
在许多环境中,可以用 < 来实现输入重定向,它将把键盘输入替换为文件输入:如果程序prog中使用了函数getchar,则命令行
// 将infile文件输入到prog
prog < infile
// 将prog的输出到文件infile中
prog > infile
将使得程序prog从输入文件infile(而不是键盘)中读取字符,实际上,程序prog并不在乎输入方式的改变,并且字符串“<infile”并不包含在argv的参数中,如果输入通过管道机制来在另一个程序中,那么这种输入切换也是不可见的。下面这个命令将otherprog的输出通过惯导重定向到程序prog的标准输入中。
otherprog | prog
使用输入输出函数的每个源文件必须在应用这些函数之前包含下列语句
#include <stdio.h>
当文件名用尖括号包含时,预处理器将在由具体实现定义的有关位置中查找指定文件(UNIX: /usr/include),找不到将在当前的项目下寻找。
二、printf
输出函数printf将内部数值转换为字符的形式,这个是大家最常用的输出函数,下面是他的完整描述,我们主要给出一些参数
int printf(char *format,...);
在字符%和转换字符中间可能依次包含以下内容:
(1)负号:指定被转换参数按照左对齐方式输出
(2)数字:指定最小字段参数
(3)小数点:将字段宽度和精度分开
(4)数字:用于指定精度,浮点数小数点后面位数,整型最少输出的数字数目
(5)字母h或者l:h将整数作为short打印,l将整型作为long打印
字符 | 参数类型;输出格式 |
---|
d,i | int类型,十进制数 | o | int类型,无符号八进制数(没有前导o) | x,X | int类型,无符号十六进制数(没有前导ox或oX),10-15分别是A-F | u | int类型,无符号十进制数 | c | int类型,单个字符 | s | char*类型,打印字符串 | f | double类型,十进制小数 [-]m.dddddd ,d的个数由精度确定,默认为6 | e,E | double类型,[-]m.dddddd e + xx,d的个数由精度确定,默认为6 | p | void*类型,指针类型 | % | 不转换参数,打印百分号 |
三、sprintf
int sprintf(char *string,char *format,arg1,arg2,...);
sprintf函数和printf函数一样,但是将输出结果放到了string中,而不是标准输出中,string必须足够大用来存放输出结果。
temp.c
#include<stdio.h>
int main(int argc,char *argv[]){
char string[1000];
char *s = "123456";
sprintf(string,"%s\n",s);
printf("%s",string);
return 0;
}
四、scanf
输入函数scanf相对应于输出函数printf,他与后者相反的方向上提供同样的转换功能,当scanf函数扫描完其格式串,或者碰到某些无法与个数控制说明匹配的情况时,函数将终止。如果达到文件结尾,给函数返回EOF,返回EOF与0是不用的,0表示出现了不匹配,EOF表示达到了文件末尾,sscanf用于从字符串中(而不是标准输入)读取字符序列。
int scanf(char *format,...)
int sscanf(char *string,char *format,...)
我们读取一个日期序列“25 Dec 1988”
#include <stdio.h>
int main(){
int day,year;
char monthname[20];
scanf("%d %s %d",&day,monthname,&year);
return 0;
}
五、文件访问
在读写一个文件之前,必须通过fopen库函数打开改文件,fopen用类似于x.c或y.c这样的外部名与操作系统之间进行某些必要的连接和通信,并返回一个随后可以用于文件读写和操作的指针。
该指针被称为文件指针,它指向一个包含文件信息的结构,这些信息包括:缓冲区的位置,缓冲区中当前字符的位置,文件的读或者写的状态、是否出错或者是否已经到达文件结尾等,用户不必关心这些细节,我们只需要声明一个文件指针,在下面例子中,请注意,FILE像int一样是一个类型名,而不是结构标记,他是通过typedef定义的。
FILE *fp;
FILE *fopen(char *name,char *mode);
void fclose(FILE *fp);
文件被打开后就需要考虑怎么读的问题,最简单的是getc
int getc(FILE *fp);
返回fp指向输入流中的下一个字符,如果到达文件末尾或者出现错误,该函数将返回EOF
int putc(int c,FILE *fp);
将字符c写入fp指定的文件中,并返回写入的字符,如果发生错误返回EOF
类似于getchar和putchar,getc和putc是宏而不是函数
启动一个c程序时,操作系统将打开三个文件,并将三个文件的指针分别提供给该程序,这三个文件分别是标准输入stdin,标准输出stdout,和标准错误stderr,他们在<stdio.h>中申明,在大多数环境中,stdin指向键盘,stdout和stderr指向显示器,但是我们知道stdin和stdout可以被重定向到文件或者管道。
那么getchar和putchar就可以被这么定义
#define getchar() getc(stdin);
#define putchar(c) putc((c),stdout);
对于文件的格式化输入和输出可以使用函数fscanf和fprintf
int fscanf(FILE *fp,char *format,...);
int fprintf(FILE *fp,char *format,...);
六、错误处理
我们可以通过向stderr写入错误信息来将输出写到错误日志内,写到stderr的输出通常也会显示到屏幕上。
#include <stdio.h>
int main() {
fprintf(stderr,"%s","this is an error example");
return 0;
}
标准库函数exit,当该函数被调用时,他将终止调用程序的执行,任何调用该程序的进程都可以获取exit的参数值,因此,可以通过另一个将该进程作为子进程的程序来测试该程序的执行是否成功,按照管理返回0表示一切正常,返回非0值通常表示出现了异常情况,
在主程序main中,语句return expr等价于exit(expr),使用exit有一个优点就是可以从其他函数中调用,整个程序中只要调用了exit就结束。
exit是结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程;而return是返回函数值并退出函数。
#include <stdio.h>
#include <stdlib.h>
int main() {
fprintf(stderr,"%s","this is an error example");
exit(1);
}
如果流fp中出现错误,则函数ferror返回一个非零值。
int ferror(FILE *fp);
如果文件到达末尾则返回一个非零值
int feof(FILE *fp);
七、行输入和行输出
char *fgets(char *line,int maxline,FILE *fp);
fgets函数从fp指向的文件中读取下一个输入行,包括换行符,并将它存放在字符数组line中,最多读取maxline-1个字符。
char *fputs(char *line,FILE *fp);
fputs将一个字符串(不需要包含换行符)写到一个文件中。
|