1)错误报告
void perror( char const * message);
打印message和当前错误代码error的信息
2)终止执行
void exit ( int status ) ;
用于终止一个程序的执行。status返回给OS,和main()返回的整树状态值相同。当程序发生错误无法继续执行 时该函数尤其有用
3)ANSI C I/O概念
流是隐藏了特定具体的I/O设备细节,使程序只需关心输入输出的字节数据。
完全缓冲:绝大部分流是完全缓冲的,输入输出的数据是通过缓冲区暂存的。这种缓冲机制可能会引起混淆。为避免printf没有即刻输出到标准输出设备。须在printf后使用fflush(stdout),fflush迫使缓冲区的数据立即写入,不管缓冲区是否已满;或者在printf的输出内容后加"/n".
流分为文本流和二进制流。流的访问和操作要通过文件(FILE)来执行。
文件(FILE):是一个数据结构,用于访问一个流。每个激活的流都有一个FILE与之关联。
文件I/O操作概览:
1。声明FILE* 指针变量
2。调用fopen函数打开流
3。对文件进行读写
4。调用fclose()关闭流。
FILE* fopen ( char const * name, char const * mode );FILE * freopen( char const * name, char const * mode, FILE * fp);
int fclose(FILE * fp); 成功返回0, 否则返回EOF
如果流中出现了错误,则函数ferror返回一个非0值:
int ferror ( FILE * fp);
如果指定的文件到达末尾,函数feof 返回一个非0值
int feof ( FILE * fp);
以下代码是将键盘输入回显到屏幕
#include
"
stdio.h
"
#include " conio.h "
#define max_length 1024
main()
{
char buffer[max_length];
while(fgets(buffer,max_length,stdin)!=NULL )
fputs(buffer,stdout);
}
#include " conio.h "
#define max_length 1024
main()
{
char buffer[max_length];
while(fgets(buffer,max_length,stdin)!=NULL )
fputs(buffer,stdout);
}
以下代码是文件拷贝:
#include
"
stdio.h
"
#include " stdlib.h "
#define max_length 1024
main()
{
char buffer[max_length];
FILE* fp;
FILE* outfp;
fp=fopen("sig_test.c","r");
if (fp == NULL)
perror("sig_test.c");
if ( (outfp = fopen("qq.c","w")) == NULL)
perror("qq.c");
while(fgets(buffer,max_length,fp)!=NULL )
{
fputs(buffer,outfp);
fflush(outfp);
}
fclose(outfp);
fclose(fp);
}
#include " stdlib.h "
#define max_length 1024
main()
{
char buffer[max_length];
FILE* fp;
FILE* outfp;
fp=fopen("sig_test.c","r");
if (fp == NULL)
perror("sig_test.c");
if ( (outfp = fopen("qq.c","w")) == NULL)
perror("qq.c");
while(fgets(buffer,max_length,fp)!=NULL )
{
fputs(buffer,outfp);
fflush(outfp);
}
fclose(outfp);
fclose(fp);
}
字符I/O
1. 输入(由getchar函数家族执行)
int fgetc( FILE* stream);int getc(FILE * stream);
int getchar (void);
每个函数都从流中读取下一个字符,并把它作为函数的返回值返回;如果流中不存在更多的字符,函数就返回常量值EOF.
注意:函数返回值类型是int ,不是char
2. 输出,可以使用putchar 函数家族
int putc ( int character , FILE * stream);
int fputc ( int character , FILE * stream);
int putchar( int character );
如果函数失败,它们返回EOF.
上面的代码只能拷贝文本文件,下面的代码可以拷贝任何文件:
#include
"
stdio.h
"
#include " stdlib.h "
#define max_length 1024
main()
... {
char buffer[max_length];
FILE* fp;
FILE* outfp;
int ch;
fp=fopen("buildarp","rb");
if (fp == NULL)
perror("buildarp");
if ( (outfp = fopen("buildarp1","wb")) == NULL)
perror("buildarp1");
while( (ch=fgetc(fp)) != EOF )
{
if (fputc(ch , outfp) == EOF)
perror("error");
}
fclose(outfp);
fclose(fp);
}
#include " stdlib.h "
#define max_length 1024
main()
... {
char buffer[max_length];
FILE* fp;
FILE* outfp;
int ch;
fp=fopen("buildarp","rb");
if (fp == NULL)
perror("buildarp");
if ( (outfp = fopen("buildarp1","wb")) == NULL)
perror("buildarp1");
while( (ch=fgetc(fp)) != EOF )
{
if (fputc(ch , outfp) == EOF)
perror("error");
}
fclose(outfp);
fclose(fp);
}
行I/O:
行I/O可以用两种方式执行,格式化的和未格式化的。这两中形式都用于操纵字符串,区别在于未格式化的I/O简单读取或写入字符串,而格式化的I/O则执行数字和其他变量的内部呢外部表示形式的转换。
1。未格式化的行I/O
gets和puts函数家族是用于操纵字符串而不是单个字符。这个特征使它们在处理一行行文本输入的程序中非常有用。
char * fgets( char* buffer , int buffer_size, FILE * stream);
char * gets( char * buffer);
int fputs( char const * buffer , FILE * stream);
int puts( char const *buffer );
如果在读取前就达到了文件末尾,缓冲区就未进行修改,fgets函数返回一个NULL指针,否则返回指向缓冲区的指针,这个返回值通常只用于检查是否到达了文件末尾。
如果写入时出现了错误,fputs返回常量值EOF, 否则它将返回一个非负值。
注意:fgets无法把字符串读入到一个长度小于两个字符的缓冲区,因为其中一个字符需要为NUL字节保留。而gets因为无缓冲区长度,因此一般不用。
UNIX 接口:
低级I/O:
int n_read = read ( int fd , char * buffrer , int n);
int n_write = write ( int fd , char * buffrer , int n);
每个调用返回实际传输的字节数。在读文件时,函数的返回值可能会小于请求的字节数。如果返回0,则表示已到达文件末尾;如果返回值为-1,则表示发生了某种错误。在写文件时,返回值是实际写入的字节数。如果返回值与实际写入的字节数不相等,则说明发生了错误。