C中采用的主要是文件指针的办法,C++中对文件的操做主要运用了“文件流”(即非标准的输入输出)的思想html
FILE *fopen(const char *filename, const char *mode)
使用给定的模式 mode 打开 filename 所指向的文件。ios
#include<stdio.h>
FILE *fopen(const char *filename, const char *mode)
filename -- 这是 C 字符串,包含了要打开的文件名称。
mode -- 这是 C 字符串,包含了文件访问模式,模式以下:c++
r 以只读方式打开文件,该文件必须存在。
r+ 以可读写方式打开文件,该文件必须存在。
rb+ 读写打开一个二进制文件,容许读数据。
rt+ 读写打开一个文本文件,容许读和写。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则创建该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创建该文件。
a 以附加的方式打开只写文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
a+ 以附加方式打开可读写的文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
wb 只写打开或新建一个二进制文件;只容许写数据。
wb+ 读写打开或创建一个二进制文件,容许读和写。
wt+ 读写打开或着创建一个文本文件;容许读写。
at+ 读写打开一个文本文件,容许读或在文本末追加数据,a表示append,就是说写入处理的时候是接着原来文件已有内容写入,不是从头写入覆盖掉,t表示打开文件的类型是文本文件,+号表示对文件既能够读也能够写。
ab+ 读写打开一个二进制文件,容许读或在文件末追加数据。windows
上述的形态字符串均可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库以二进制模式打开文件。若是不加b,表示默认加了t,即rt,wt,其中t表示以文本模式打开文件。由fopen()所创建的新文件会具备S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。数组
有些C编译系统可能不彻底提供全部这些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,读者注意所用系统的规定。缓存
文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:app
r(read): 读 w(write): 写 a(append): 追加 t(text): 文本文件,可省略不写 b(banary): 二进制文件 +: 读和写
1.在windows系统中,文本模式下,文件以"\r\n"表明换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。函数
2.在类Unix/Linux系统中文本模式下,文件以"\n"表明换行。因此Linux系统中在文本模式和二进制模式下并没有区别。
返回值 : 若是文件顺利打开,返回指向该流的文件指针。若是文件打开失败则返回NULL,并把错误代码存在error中。spa
通常而言,打开文件后会做一些文件读取或写入的动做,若打开文件失败,接下来的读写动做也没法顺利进行,因此通常在fopen()后做错误判断及处理。操作系统
1.做用: 在C语言中fopen()函数用于打开指定路径的文件,获取指向该文件的指针。
2.函数原型:
FILE * fopen(const char * path,const char * mode); -- path: 文件路径,如:"F:\Visual Stdio 2012\test.txt" -- mode: 文件打开方式,例如: "r" 以只读方式打开文件,该文件必须存在。 "w" 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则创建该文件。 "w+" 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创建该文件。 "a" 以附加的方式打开只写文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留) "a+" 以附加方式打开可读写的文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。(原来的EOF符不保留) "wb" 只写打开或新建一个二进制文件,只容许写数据。 "wb+" 读写打开或创建一个二进制文件,容许读和写。 "ab" 追加打开一个二进制文件,并在文件末尾写数据。 "ab+"读写打开一个二进制文件,容许读,或在文件末追加数据。 --返回值: 文件顺利打开后,指向该流的文件指针就会被返回。若是文件打开失败则返回NULL,并把错误代码存在errno中。
1.做用:在C语言中fwrite()函数经常使用语将一块内存区域中的数据写入到本地文本。
2.函数原型:
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream); -- buffer:指向数据块的指针 -- size:每一个数据的大小,单位为Byte(例如:sizeof(int)就是4) -- count:数据个数 -- stream:文件指针
注意:
返回值随着调用格式的不一样而不一样:
(1) 调用格式:fwrite(buf,sizeof(buf),1,fp);
成功写入返回值为1(即count)
(2)调用格式:fwrite(buf,1,sizeof(buf),fp);
成功写入则返回实际写入的数据个数(单位为Byte)
写完数据后要调用fclose()关闭流,不关闭流的状况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。
代码1: 下面代码可将1024个字(int)写入到文本文件,fwrite的调用中,size是sizeof(int),count是DATA_SIZE
#include "stdafx.h" #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define DATA_SIZE 1024 int main() { unsigned int *dataPtr = NULL; dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE); for(unsigned int i=0;i<DATA_SIZE;i++) { dataPtr[i] = i; //初始化缓存区 } FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","w"); fwrite(dataPtr,sizeof(int),DATA_SIZE,fp); fclose(fp); free(dataPtr); system("pause"); return 0; }
代码2:
下面代码也可将1024个字写到文本中,虽然fwrite函数中,size是1,但count是DATA_SIZE*sizeof(int)。与代码1实现的结果同样。
// datasave.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define DATA_SIZE 1024 int main() { unsigned int *dataPtr = NULL; dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE); for(unsigned int i=0;i<DATA_SIZE;i++) { dataPtr[i] = i; //初始化缓存区 } FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+"); fwrite(dataPtr,1,DATA_SIZE*sizeof(unsigned int),fp); fclose(fp); free(dataPtr); system("pause"); return 0; }
下面的代码将4096个char数据写到文本,写入的数据中,最大值为255,与上面代码一、2有区别,由于缓存区数据类型不一样
// datasave.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define DATA_SIZE 1024 int main() { unsigned char *dataPtr = NULL; dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE); //申请的区域是4096个char,即1024个字的区域 for(unsigned int i=0;i<DATA_SIZE;i++) { dataPtr[i] = i; //初始化缓存区 } FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+"); fwrite(dataPtr,sizeof(char),DATA_SIZE*sizeof(int),fp); fclose(fp); free(dataPtr); system("pause"); return 0; }
用malloc函数申请区域时是申请的一片char*区域,经过强制类型转换后可装unsigned int 数据。
// datasave.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define DATA_SIZE 1024 int main() { unsigned char *dataPtr = NULL; unsigned int *Ptr = NULL; dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE); Ptr = (unsigned int *) dataPtr; for(unsigned int i=0;i<DATA_SIZE;i++) { Ptr[i] = i; } FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+"); fwrite(Ptr,sizeof(unsigned int),DATA_SIZE,fp); fclose(fp); free(dataPtr); system("pause"); return 0; }
size_t fread(void *buffer, size_t size, size_t count, FILE *stream); -- buffer:指向数据块的指针 -- size:每一个数据的大小,单位为Byte(例如:sizeof(int)就是4) -- count:数据个数 -- stream:文件指针
注意:返回值随着调用格式的不一样而不一样:
(1) 调用格式:fread(buf,sizeof(buf),1,fp);
读取成功时:当读取的数据量正好是sizeof(buf)个Byte时,返回值为1(即count)
不然返回值为0(读取数据量小于sizeof(buf))
(2)调用格式:fread(buf,1,sizeof(buf),fp);
读取成功返回值为实际读回的数据个数(单位为Byte)
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *filp = NULL; char fileDir[] = "/home/yangzhiyuan/Documents/test.txt"; char dataPtr[] = "Helloworld"; printf("sizeof(dataPtr) = %ld\n",sizeof(dataPtr)); filp = fopen(fileDir,"w+"); /* 可读可写,不存在则建立 */ int writeCnt = fwrite(dataPtr,sizeof(dataPtr),1,filp); /* 返回值为1 */ //int writeCnt = fwrite(dataPtr,1,sizeof(dataPtr),filp); /* 返回值为11 */ printf("writeCnt = %d\n",writeCnt); fclose(filp); FILE *fp = NULL; fp = fopen(fileDir,"r"); char buffer[256]; int readCnt = fread(buffer,sizeof(buffer),1,fp); /* 返回值为0 */ //int readCnt = fread(buffer,1,sizeof(buffer),fp); /* 返回值为11 */ printf("readCnt = %d\n",readCnt); fclose(fp); printf("%s\n",buffer); exit(0); }
本例代码中定义了两个FILE变量,一个用于write,一个用于read,写完后要close掉,而后再打开,而后读。若是直接使用一个FILE变量,会出错!
// 读取文件块数据 size_t fread(void *buffer, size_t size, size_t count, FILE *file); // 写入文件块数据 size_t fwrite(const void *buffer, size_t size, size_t count, FILE *file);
fread参数说明:buffer是读取数据后存放地址,size是的块长度,count是块的数量,实际读取长度为size*count,返回值为块成功读取块的count数量。
fwrite参数说明:buffer是写入数据后存放地址,size是的块长度,count是块的数量,实际读取长度为size*count,返回值为块成功写入快的count数量。
写文件
#include <stdio.h> #include <stdlib.h> int main() { FILE * fp; fp = fopen ("file.txt", "w+"); fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014); fclose(fp); return(0); }
输出
We are in 2014
查看上面的内容:
#include <stdio.h> int main () { FILE *fp; int c; fp = fopen("file.txt","r"); while(1) { c = fgetc(fp); if( feof(fp) ) { break ; } printf("%c", c); } fclose(fp); return(0); }
#include <fstream>
fstream提供三种类,实现C++对文件的操做
ofstream:写操做,由ostream引伸而来
ifstream:读操做,由istream引伸而来
fstream :同时读写操做,由iostream引伸而来
文本文件 和 二进制文件
ios::in 为输入(读)而打开文件;
ios::out 为输出(写)而打开文件;
ios::ate 初始位置:文件尾;
ios::app 全部输出附加在文件末尾;
ios::trunc 若是文件已存在则先删除该文件;
ios::binary 二进制方式;
ios::nocreate:不创建文件,因此文件不存在时打开失败;
ios::noreplace:不覆盖文件,因此打开文件时若是文件存在失败;
这些标识符能够被组合使用,中间以”或”操做符(|)间隔。例如,若是咱们想要以二进制方式打开文件"example.bin" 来写入一些数据,咱们能够经过如下方式调用成员函数open()来实现:
ofstream file; file.open ("example.bin", ios::out | ios::app | ios::binary);
ofstream, ifstream 和 fstream全部这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同:
ofstream 默认方式 ios::out | ios::trunc
ifstream 默认方式 ios::in
fstream 默认方式 ios::in | ios::out
只有当函数被调用时没有声明方式参数的状况下,默认值才会被采用。若是函数被调用时声明了任何参数,默认值将被彻底改写,而不会与调用参数组合。
因为对类ofstream, ifstream 和 fstream 的对象所进行的第一个操做一般都是打开文件,这些类都有一个构造函数能够直接调用open 函数,并拥有一样的参数。这样,咱们就能够经过如下方式进行与上面一样的定义对象和打开文件的操做:
ofstream file ("example.bin", ios::out | ios::app | ios::binary);
两种打开文件的方式都是正确的。
你能够经过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:
bool is_open();
它返回一个布尔(bool)值,为真(true)表明文件已经被顺利打开,假( false )则相反。
关闭文件(Closing a file)
当文件读写操做完成以后,咱们必须将文件关闭以使文件从新变为可访问的。关闭文件须要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单:
void close ();
这个函数一旦被调用,原先的流对象(stream object)就能够被用来打开其它的文件了,这个文件也就能够从新被其它的进程(process)全部访问了。
为防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close。
除了eof()之外,还有一些验证流的状态的成员函数(全部都返回bool型返回值):
bad()
若是在读写过程当中出错,返回 true 。例如:当咱们要对一个不是打开为写状态的文件进行写入时,或者咱们要写入的设备没有剩余空间的时候。
fail()
除了与bad() 一样的状况下会返回 true 之外,加上格式错误时也返回true ,例如当想要读入一个整数,而得到了一个字母的时候。
eof()
若是读文件到达文件末尾,返回true。
good()
这是最通用的:若是调用以上任何一个函数返回true 的话,此函数返回 false 。
要想重置以上成员函数所检查的状态标志,你可使用成员函数clear(),没有参数。
一、包含的头文件:#include
二、建立流
三、打开文件(文件和流关联)
四、读写 (写操做:<<,put( ), write( ) 读操做: >> , get( ),getline( ), read( ))
五、关闭文件:把缓冲区数据完整地写入文件, 添加文件结束标志, 切断流对象和外部文件的链接
一、文本文件的读写:
方法:
一次性读写若干字符
1)使用运算符<< 和 >>进行读写 功能: << 能实现以行为单位写入文件 >> 不能一行为单位读入内存,老是以空格、Tab、回车结束,而是以单词为单位
代码:
函数功能:使用<< ,写入文件一行字符
#include <fstream> #include <iostream> using namespace std; void main() { ofstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile<<"abc def ghi"; OpenFile.close(); system("pause"); }
运行结果:文件中写入内容:abc def ghi
函数功能:使用>>,从文件读入一个单词
#include <fstream> #include <iostream> using namespace std; void main() { const int len=20; char str[len]; ifstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile>>str; cout<<str<<endl; OpenFile.close(); system("pause"); }
运行结果:str的内容为abc,而不是abc def ghi(见空格中止)
功能: <<:以行为单位输入文件 getline():以行为单位 读入内存,能一次读入一行 函数原型:istream &getline( char *buffer, streamsize num ); 功能:getline( )函数用于从文件读取num-1个字符到buffer(内存)中,直到下列状况发生时,读取结束: 1):num - 1个字符已经读入 2):碰到一个换行标志 3):碰到一个EOF
代码:
#include <fstream> #include <iostream> using namespace std; void main() { const int len=20; char str[len]; ifstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile.getline(str,20); cout<<str<<endl; OpenFile.close(); system("pause"); }
运行结果:str的内容为abc def ghi (一直把一行读完)
使用get( )和put( )函数
函数声明:istream& get(char &c);
函数功能:使用 get( )函数 把字符1输入到文件
#include <fstream> #include <iostream> using namespace std; void main() { char ch='1'; ofstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile.put(ch); OpenFile.close(); system("pause"); }
运行结果:把字符1写入文件
函数功能:使用 put( )函数 把文件中第一个字符输入内存
#include <fstream> #include <iostream> using namespace std; void main() { char ch; ifstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile.get(ch); cout<<ch; OpenFile.close(); system("pause"); }
运行结果:把字符1从文件中读到ch(内存)中
1)使用运算符get( ) 和 put( )读写一个字节
功能:
get( ) :在文件中读取一个字节到内存
函数原型:ifstream &get(char ch)
put( ) :在内存中写入一个字节到文件
函数原型:ofstream &put(char ch)
代码:
功能:把26个字符写入文件中
#include <fstream> #include <iostream> using namespace std; void main() { char ch='a'; ofstream OpenFile("file.txt",ios::binary); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } for (int i=0;i<26;i++) { OpenFile.put(ch); ch++; } OpenFile.close(); system("pause"); }
运行结果:文件内容为abcdefghijklmnopqlst...z
功能:把文件中的26个字母读入内存
#include <fstream> #include <iostream> using namespace std; void main() { char ch; ifstream OpenFile("file.txt",ios::binary); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } while (OpenFile.get(ch)) cout<<ch; OpenFile.close(); system("pause"); }
运行结果:ch依次为abc...z
read( ):
功能:从文件中提取 n 个字节数据,写入buf指向的地方中 函数声明:istream & read ( char * buf , int n ) ;
代码:
函数功能:使用write( )函数,一次从内存向文件写入一行数据
#include <fstream> #include <iostream> using namespace std; void main() { char ch[12]="12 3 456 78"; ofstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile.write(ch,12); OpenFile.close(); system("pause"); }
运行结果:文件内容12 3 456 78
write( ):
功能:把buf指向的内容取n个字节写入文件 函数声明:ostream & ostream :: write ( char * buf , int n ) ; 参数说明:buf表示要写入内存的地址,传参时要取地址。n表示要读入字节的长度 注意:1):该函数遇到空字符时并不中止,于是可以写入完整的类结构 2):第一个参数一个char型指针(指向内存数据的起始地址),与对象结合使用的时候,要在对象地址以前要char作强制类型转换。
函数功能:使用write( )函数,一次从文件向内存写入一行数据
#include <fstream> #include <iostream> using namespace std; void main() { char ch[12]; ifstream OpenFile("file.txt"); if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); } OpenFile.read(ch,12); cout<<ch; OpenFile.close(); system("pause"); }
运行结果:数组ch的内容为12 3 456 78 。
一、程序再也不使用文件时,为何要关闭文件?
由于:
1)文件缓冲区是一块小的内存空间.
2)操做系统限制同时打开的文件数量
注意:close ( ) 函数关闭文件,但流对象仍然存在。
二、文件的默认打开方式为文本文件,要是想以二进制的方式处理,在打开时要用 ios::binary 显式声明。
三、针对文本文件操做时,get函数和>>的区别:
区别:在读取数据时,get函数包括空白字符(遇空白字符不中止读取)
>>在默认状况下拒绝接受空白字符(遇到空白符中止读取)
四、判断文件是否打开的方法:
if (OpenFile) { cout<<"打开文件失败!"; exit(0); } if (OpenFile.fail()) { cout<<"打开文件错误!"<<endl; exit(0); }
1)使用成员函数eof()能够检测到这个结束符,若是非0表示文件结束。
while (!OpenFile.eof()) { //文件结束时的代码 }
2)使用流直接检测,若是为0表示文件结束
while (!OpenFile) { //文件结束时的代码 }
3)使用get函数,读取最后一个结束符时,返回0.读取正常状况下,返回1,并把读取的字符放到ch中
while ( (OpenFile.get(ch) )!=EOF) { //成功时候的代码 }
文本文件的读写常使用的方法:使用<<写入文件,使用getline 和 >> 读到内存
二进制文件的读写常使用的方法:使用istream 类的成员函数read 和write 来实现,
这两个成员函数的原型为:
istream& read(char *buffer,int len); ostream& write(const char * buffer,int len);
参数说明:字符指针 buffer 指向内存中一段存储空间。len 是读/写的字节数。
与对象结合写入二进制文件时:
输出文件流对象名.write((char*)& 对象名,sizeof(<对象所属类名>)); 输出文件流对象名.write((char*)& 对象数组名[下标],sizeof(<对象所属类名>));
输入文件流对象名.read((char*)& 对象名,sizeof(<对象所属类名>)); 输入文件流对象名.read((char*)& 对象数组名[下标],sizeof(<对象所属类名>));
注意:gcount()函数常常和read函数配合使用,用来得到实际读取的字节数。
#include <iostream> #include <fstream> using namespace std; int main(void) { //写文件:二进制存储1234 int writeNum1 = 1; int writeNum2 = 2; int writeNum3 = 3; int writeNum4 = 4; ofstream fout("test.txt", ios::out | ios::binary); fout.write(reinterpret_cast<char *>(&writeNum1), sizeof(int)); fout.write(reinterpret_cast<char *>(&writeNum2), sizeof(int)); fout.write(reinterpret_cast<char *>(&writeNum3), sizeof(int)); fout.write(reinterpret_cast<char *>(&writeNum4), sizeof(int)); fout.close(); //读文件 ifstream fin("test.txt",ios::in | ios::binary); if (!fin.good()) { cout<<"文件打开错误"<<endl; exit(0); } int readNum = 0; //第一次输出:从第一个数字输出,结果是1 2 3 4 fin.seekg(0,ios::beg); while (fin.peek() != EOF) { fin.read(reinterpret_cast<char*>(&readNum), sizeof(int)); cout<<readNum<<" "; } cout<<endl; //第二次输出:从第三个数字输出,结果是3 4 fin.seekg(2 * sizeof(int),ios::beg);//游标移动的次数 = 须要处理数的个数 × int占的字节数 while (fin.peek() != EOF) { fin.read(reinterpret_cast<char*>(&readNum), sizeof(int)); cout<<readNum<<" "; } cout<<endl; fin.close(); system("pause"); return 0; }