1. C语言文件操作分为两类,分为 文本文件操作 和二进制文件操作。
头文件是: #include <stdio.h>
2. fopen() 函数:
FILE *fopen(const char *path, const char *mode);
参数:
path --- 文件所在的路径
mode --- 打开文件的模式,表示流形态。有下列几种形态字符串:
r // 以只读方式打开文件,该文件必须存在。
r+ // 以可读写方式打开文件,该文件必须存在。
rb+ // 读写打开一个二进制文件,允许读数据。
rw+ //读写打开一个文本文件,允许读和写。
w //打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ //打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a //以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
a+ //以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
wb //只写打开或新建一个二进制文件;只允许写数据。
wb+ //读写打开或建立一个二进制文件,允许读和写。
ab+ //读写打开一个二进制文件,允许读或在文件末追加数据。
at+ //打开一个叫string的文件,a表示append,就是说写入处理的时候是接着原来文件已有内容写入,不是从头写入覆盖掉,t表示打开文件的类型是文本文件,+号表示对文件既可以读也可以写。
上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库以二进制模式打开文件。
如果不加b,表示默认加了t,即rt,wt,其中t表示以 文本模式打开文件。
由f open()所建立的新 文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。
如果不加b,表示默认加了t,即rt,wt,其中t表示以 文本模式打开文件。
由f open()所建立的新 文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。
二进制和文本模式的区别
1.在windows系统中,文本模式下,文件以""代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"" 。
2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
对于linux 和 unix这样只有一种文件类型的系统,带b 和不带b的模式是相同的。
3. fclose(FILE *fd) --- 打开文件后必须要关闭文件。
int fclose(FILE *fp);
4. fgetc() --- 读取文件中的单个字符
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
5. fputc() 函数 --- 把字符写入文件
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
6. fprintf(), fscanf(), fgets(), fputs() ---文件,字符输入输出
7. fseek(), ftell() 函数
int fseek(FILE *stream, long offset, int fromwhere);
fseek 用于二进制方式打开的文件,移动文件读写指针位置.
fseek(in,-1L,1); -- 文件流in, 零点为当前指针位置,SEEK_CUR 就是 1, -1L -- 文件指针回退1个字节int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
简言之:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。
long ftell(FILE *stream);
The ftell() function obtains the current value of the file position indicator for the stream pointed to by stream.
这两个函数可以一起使用,用来计算二进制文件的大小:
计算二进制文件大小:
int filesize(char *filename)
{
int length = 0;
FILE *fp = fopen(filename,"rb");
if(fp==NULL)
{
return -1;
}
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fclose(fp);
return length;
}
8. fread(), fwrite() --- 读写文件
SYNOPSIS
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
DESCRIPTION
The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.
For non-locking counterparts, see unlocked_stdio(3).
RETURN VALUE
fread() and fwrite() return the number of items successfully read or written (i.e., not the number of characters). If an error occurs, or the end-of-file is
reached, the return value is a short item count (or zero).
fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.
9. fgetpos(), fsetpos() --- 获取和设置文件位置指针
fgetpos():
#include <string.h>
#include <stdio.h>
int main(void)
{
FILE *stream;
char string[] = "This is a test";
fpos_t filepos;
/* open a file for update */
stream = fopen("DUMMY.FIL", "w+");
/* write a string into the file */
fwrite(string, strlen(string), 1, stream);
/* report the file pointer position */
fgetpos(stream, &filepos);
printf("The file pointer is at byte\
%ld\n", filepos);
fclose(stream);
return 0;
}
fsetpos():
#include <stdlib.h>
#include <stdio.h>
void showpos(FILE *stream);
int main(void)
{
FILE *stream;
fpos_t filepos;
/* open a file for update */
stream = fopen("DUMMY.FIL", "w+");
/* save the file pointer position */
fgetpos(stream, &filepos);
/* write some data to the file */
fprintf(stream, "This is a test");
/* show the current file position */
showpos(stream);
/* set a new file position, display it */
if (fsetpos(stream, &filepos) == 0)
showpos(stream);
else
{
fprintf(stderr, "Error setting file \
pointer.\n");
exit(1);
}
/* close the file */
fclose(stream);
return 0;
}
void showpos(FILE *stream)
{
fpos_t pos;
/* display the current file pointer
position of a stream */
fgetpos(stream, &pos);
printf("File position: %ld\n", pos);
}
10. ungetc() --- 把一个字符退回到输入流中
int ungetc(char c, FILE *stream);
输入参数
c 要写入的字符,stream 文件流指针
输出参数
字符c - 操作成功,EOF - 操作失败
代码:
代码:
代码:
#include <stdio.h>
#include <ctype.h>
void main( void )
{
int ch;
int result = 0;
printf( "Enter an integer: \n" );
/* Read in and convert number: */
while( ((ch = getchar()) != EOF) && isdigit( ch ) ) // isdigit(ch) return 0 when ch is not a digit.
result = result * 10 + ch - '0'; /* Use to format digit. */
if( ch != EOF )
ungetc(ch, stdin ); /* Put nondigit back. */
printf( "Number = %d\nNextcharacter in stream = '%c'\n",
result, getchar() );
}
11. fflush()
功 能: 清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件
头文件:<stdio.h>
原型:int fflush(FILE *stream)
代码:
#include <string.h>
#include <stdio.h>
#include "conio.h"
#include "io.h"
void flush(FILE *stream);
int main(void)
{
FILE *stream;
char msg[] = "This is a test";
/* create a file */
stream = fopen("DUMMY.FIL", "w");
/* write some data to the file */
fwrite(msg, strlen(msg), 1, stream);
clrscr();
printf("Press any key to flush DUMMY.FIL:");
getch();
/* flush the data to DUMMY.FIL without\
closing it */
flush(stream);
printf("\nFile was flushed, Press any key\to quit:");
getch();
return 0;
}
void flush(FILE *stream)
{
int duphandle;
/* flush the stream's internal buffer */
fflush(stream);
/* make a duplicate file handle */
duphandle = dup(fileno(stream));
/* close the duplicate handle to flush the DOS buffer */
close(duphandle);
}
12. setvbuf() --- 把缓冲区与流相关
用 法: int setvbuf(FILE *stream, char *buf, int type, unsigned size);
参数:stream :指向流的指针 ;
buf : 期望缓冲区的地址;
type : 期望缓冲区的类型:
_IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据。
_IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据。
_IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区。
size : 缓冲区内字节的数量。
注意:This function should be called once the file associated with the stream has already been opened but before any input or output operation has taken place.
意思是这个函数应该在打开流后,立即调用,在任何对该流做输入输出前。
代码:
#include <stdio.h>
int main(void)
{
FILE *input, *output;
char bufr[512];
input = fopen("file.in", "r+b");
output = fopen("file.out", "w");
/* set up input stream for minimal disk access,
using our own character buffer */
if (setvbuf(input, bufr, _IOFBF, 512) != 0)
printf("failed to set up buffer for input file\n");
else
printf("buffer set up for input file\n");
/* set up output stream for line buffering using space that
will be obtained through an indirect call to malloc */
if (setvbuf(output, NULL, _IOLBF, 132) != 0)
printf("failed to set up buffer for output file\n");
else
printf("buffer set up for output file\n");
/* perform file I/O here */
/* close files */
fclose(input);
fclose(output);
return 0;
}
13. feof() 和 ferror()
feof() 最近一次输入调用检测到文件尾部,到文件尾部返回一个非0值,否则返回0。
ferror() 用来检测发生读写错误,发生错误返回非0值,否则返回0。