C C++ 文件输入与输出
C语言:
一 打开关闭文件
1 fopen函数 用于打开文件
FILE *fopen(char *filename, *type);
fopen("c:\\ccdos\\clib", "rb"); 如果成功的打开一个文件, fopen()函数返回文件指针,否则返回空指针(NULL)。由此可判断文件打开是否成功。
"r" 打开文字文件只读
"w" 创建文字文件只写
"a" 增补,如果文件不存在则创建一个
"r+" 打开一个文字文件读/写
"w+" 创建一个文字文件读/写
"a+" 打开或创建一个文件增补
"b" 二进制文件(可以和上面每一项合用)
"t" 文这文件(默认项)
2. fclose()函数
fclose()函数用来关闭一个由fopen()函数打开的文件,其调用格式为:
int fclose(FILE *stream);该函数返回一个整型数。当文件关闭成功时,返回0,否则返回一个非零值。可以根据函数的返回值判断文件是否关闭成功。
二 有关文件操作的函数
本节所涉及到的文件读写函数均是指顺序读写,即读写了一条信息后,指针自动加1.
下面分别介绍写操作函数和读操作函数。
1. 文件的顺序写函数
fprintf()、fputs()和fputc()函数均为文件的顺序写操作函数,其调用格式如下:
int fprintf(FILE *stream, char *format, <variable-list>);
int fputs(char *string, FILE *steam);
int fputc(int ch, FILE *steam); 上述三个函数的返回值均为整型量。
fprintf() 函数的返回值为实际写入文件中的字符个数(字节数)。如果写错误,则返回一个负数;
fputs()函数返回0时表明将string指针所指的字符串写入文件中的操作成功, 返回非0时,表明写操作失败。
fputc()函数返回一个向文件所写字符的值,此时写操作成功,否则返回EOF(文件结束结束其值为-1, 在stdio.h中定义)表示写操作错误。
fprintf( ) 函数中格式化的规定与printf( ) 函数相同,所不同的只是fprintf()函数是向文件中写入。而printf()是向屏幕输出。
例如:
fputs("Your score of TOEFLis", fp);/*向所建文件写入一串字符*/
fputc(':', fp); /*向所建文件写冒号:*/
fprintf(fp, "%d\n", i); /*向所建文件写一整型数*/
fprintf(fp, "%s", s); /*向所建文件写一字符串*/
2. 文件的顺序读操作函数
函数fscanf()、fgets()和fgetc()均为文件的顺序读操作函数,其调用格式如下:
int fscanf(FILE *stream, char *format, <address-list>);
char fgets(char *string, int n, FILE *steam);
int fgetc(FILE *steam);
fscanf()函数的用法与scanf()函数相似,只是它是从文件中读到信息。 fscanf()函数的返回值为EOF(即-1), 表明读错误,否则读数据成功。读到空白字符自动返回。
fgets()函数从文件中读取至多n-1个字符(n用来指定字符数), 并把它们放入string指向的字符串中,在读入之后自动向字符串未尾加一个空字符,读成功返回string指针,失败返回一个空指针。
fgetc()函数返回文件当前位置的一个字符,读错误时返回EOF。
3. 文件的随机读写
有时用户想直接读取文件中间某处的信息, 若用文件的顺序读写必须从文件 头开始直到要求的文件位置再读, 这显然不方便。Turbo C2.0提供了一组文件的 随机读写函数, 即可以将文件位置指针定位在所要求读写的地方直接读写。
文件的随机读写函数如下:
int fseek (FILE *stream, long offset, int fromwhere);
int fread(void *buf, int size, int count, FILE *stream);
int fwrite(void *buf, int size, int count, FILE *stream);
long ftell(FILE *stream);
fseek()函数的作用是将文件的位置指针设置到从fromwhere开始的第offset 字节的位置上, 其中fromwhere是下列几个宏定义之一:
文件位置指针起始计算位置fromwhere
━━━━━━━━━━━━━━━━━━━━━━━━━━━
符号常数 数值 含义
───────────────────────────
SEEK_SET 0 从文件开头
SEEK_CUR 1 从文件指针的现行位置
SEEK_END 2 从文件末尾
━━━━━━━━━━━━━━━━━━━━━━━━━━━
offset是指文件位置指针从指定开始位置(fromwhere指出的位置)跳过的字节数。它是一个长整型量, 以支持大于64K字节的文件。
fseek()函数一般用于对 二进制文件进行操作。当fseek()函数返回0时表明操作成功, 返回非0表示失败。
fread()函数是从文件中读count个字段, 每个字段长度为size个字节, 并把 它们存放到buf指针所指的缓冲器中。
fwrite()函数是把buf指针所指的缓冲器中, 长度为size个字节的count个字 段写到stream指向的文件中去。
随着读和写字节数的增大, 文件位置指示器也增大, 读多少个字节, 文件位 置指示器相应也跳过多少个字节。读写完毕函数返回所读和所写的字段个数。
ftell()函数返回文件位置指示器的当前值,这个值是指示器从文件头开始 算起的字节数, 返回的数为长整型数, 当返回-1时, 表明出现错误。
下面程序把一个浮点数组以二进制方式写入文件test_b.dat中。
例14:
#include <stdio.h>
main()
{
float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5};
/*定义浮点数组并初始化*/
int i;
FILE *fp;
fp=fopen("test_b.dat", "wb"); /*创建一个二进制文件只写*/
fwrite(f, sizeof(float), 6, fp);/*将6个浮点数写入文件中*/
fclose(fp); /*关闭文件*/
}
下面例子从test_b.dat文件中读100个整型数, 并把它们放到dat数组中。 例15:
#include <stdio.h>
main()
{
FILE *fp;
intdat[100];
fp=fopen("test_b.dat", "rb");/*打开一个二进制文件只读*/
if(fread(dat, sizeof(int), 100, fp)!=100)
/*判断是否读了100个数*/
{
if(feof(fp))
printf("End of file"); /*不到100个数文件结束*/
else
printf("Read error"); /*读数错误*/
fclose(fp); /*关闭文件*/
}
注意:
当用标准文件函数对文件进行读写操作时, 首先将所读写的内容放进缓冲区, 即写函数只对输出缓冲区进行操作, 读函数只对输入缓冲区进行操作。例如向一 个文件写入内容, 所写的内容将首先放在输出缓冲区中, 直到输出缓冲区存满或使用fclose()函数关闭文件时, 缓冲区的内容才会写入文件中。若无fclose()函数, 则不会向文件中存入所写的内容或写入的文件内容不全。有一个对缓冲区 进行刷新的函数, 即fflush(), 其调用格式为:
int fflush(FILE *stream);该函数将输出缓冲区的内容实际写入文件中, 而将输入缓冲区的内容清除掉。
4. feof()和rewind()函数
这两个函数的调用格式为:
int feof(FILE *stream);
int rewind(FILE *stream);
feof()函数检测文件位置指示器是否到达了文件结尾,若是则返回一个非0值, 否则返回0。这个函数对二进制文件操作特别有用, 因为二进制文件中,文件结尾标志EOF也是一个合法的二进制数,只简单的检查读入字符的值来判断文件是否结束是不行的。如果那样的话, 可能会造成文件未结尾而被认为结尾, 所以就必须有feof()函数。
下面的这条语句是常用的判断文件是否结束的方法。
while(!feof(fp))
fgetc(fp);
rewind()函数用于把文件位置指示器移到文件的起点处, 成功时返回0,否则, 返回非0值。
C语言本身并不提供输入输出语句,输入和输出操作是由函数来实现的。在C标准函数库中提供了一些输入输出函数,例如,printf函数和scanf函数。
基于C++的文件操作
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
1、插入器(<<) 向流输出数据。比如说系统有一个默认的标准输出流(cout),一般情况下就是指的显示器,所以,cout<<"Write Stdout"<<'\n';就表示把字符串"Write Stdout"和换行字符('\n')输出到标准输出流。
2、析取器(>>) 从流中输入数据。比如说系统有一个默认的标准输入流(cin),一般情况下就是指的键盘,所以,cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。
在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
一、打开文件 在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
void open(const char* filename,int openmode,int access);
参数:
filename: 要打开的文件名 mode: 要打开文件的方式
access: 打开文件的属性 打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:
ios::app: 以追加的方式打开文件 ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文 ios::in: 文件以输入方式打开(文件=>程序) ios::out: 文件以输出方式打开 (程序=>文件) ios::nocreate: 不建立文件,所以文件不存在时打开失败 ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc: 如果文件存在,把文件长度设为0 可以用“或”把以上属性连接起来,如ios::out|ios::binary
打开文件的属性取值是:
0:普通文件,打开访问 1:只读文件 2:隐含文件 4:系统文件 可以用“或”或者“+”把以上属性连接起来 ,如3或1|2就是以只读和隐含属性打开文件。
例如:以二进制输入方式打开文件c:\config.sys
fstream file1; file1.open("c:\\config.sys",ios::binary|ios::in,0);
如果open函数只有文件名一个参数,则是以读/写普通文件打开,即:
file1.open("c:\\config.sys");<=>file1.open("c:\\config.sys",ios::in|ios::out,0);
另外,fstream还有和open()功能一样的构造函数,对于上例,在定义的时侯就可以打开文件了:
fstream file1("c:\\config.sys");
特别提出的是,fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream),ifstream默认以输入方式打开文件(文件=>程序),而ofstream默认以输出方式打开文件。
ifstream file2("c:\\pdos.def");//以输入方式打开文件 ofstream file3("c:\\x.123");//以输出方式打开文件
所以,在实际应用中,根据需要的不同,选择不同的类来定义:如果想以输入方式打开,就用ifstream来定义;如果想以输出方式打开,就用ofstream来定义;如果想以输入/输出方式来打开,就用fstream来定义。
二、关闭文件 打开的文件使用完成后一定要关闭,fstream提供了成员函数close()来完成此操作,如:file1.close();就把file1相连的文件关闭。
三、读写文件 读写文件分为文本文件和二进制文件的读取,对于文本文件的读取比较简单,用插入器和析取器就可以了;而对于二进制的读取就要复杂些,下要就详细的介绍这两种方式
1、文本文件的读写 文本文件的读写很简单:用插入器(<<)向文件输出;用析取器(>>)从文件输入。假设file1是以输入方式打开,file2以输出打开。示例如下:
file2<<"I Love You";//向文件写入字符串"I Love You" int i; file1>>i;//从文件输入一个整数值。
这种方式还有一种简单的格式化能力,比如可以指定输出为16进制等等,具体的格式有以下一些
操纵符 功能 输入/输出 dec 格式化为十进制数值数据 输入和输出 endl 输出一个换行符并刷新此流 输出 ends 输出一个空字符 输出 hex 格式化为十六进制数值数据 输入和输出 oct 格式化为八进制数值数据 输入和输出
setpxecision(int p) 设置浮点数的精度位数 输出
比如要把123当作十六进制输出:file1<<<123;要把3.1415926以5位精度输出:file1<<<3.1415926。
2、二进制文件的读写 ①put() put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。
②get() get()函数比较灵活,有3种常用的重载形式:
一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。
另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。
还有一种形式的原型是:ifstream &get(char *buf,int num,char delim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用 delim 这个参数,将使用缺省值换行符'\n'。例如:
file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。
③读写数据块 要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:
read(unsigned char *buf,int num); write(const unsigned char *buf,int num);
read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *,有时可能需要类型转换。
例:
unsigned char str1[]="I Love You"; int n[5]; ifstream in("xxx.xxx"); ofstream out("yyy.yyy"); out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中 in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换 in.close();out.close();
四、检测EOF 成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();
例: if(in.eof())ShowMessage("已经到达文件尾!");
五、文件定位 和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时, 相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是 seekg()和 seekp(),seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下:
istream &seekg(streamoff offset,seek_dir origin); ostream &seekp(streamoff offset,seek_dir origin);
streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
ios::beg: 文件开头 ios::cur: 文件当前位置 ios::end: 文件结尾
这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。
例:
file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节 file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节
-------------------------------------------------------------------------------------------------------------------------------------------------------------
文本文件读写:
#include <fstream>
#include <iostream>
using namespace std; int main()
{
//文本文件打开方式设为可读写
// fstream outfile("f1.dat",ios::out|ios::in);
// if (!outfile)
// {
// cout<<"open error!"<<endl;
// exit(1);
// } // char a[10];
// cout<<"输入十个数字"<<endl;
// //写入文件中
// for (int i=0;i<10;i++)
// {
// cin>>a[i];
// outfile<<a[i]<<' ';
// }
// //从文件读取
// for (int i=0;i<10;i++)
// {
// outfile>>a[i];
// cout<<a[i]<<' ';
// }
// outfile.close(); //从键盘读入一行字符,将其中的字母存在磁盘文件
// ofstream outfile("f2.dat");
// if (!outfile)
// {
// cout<<"open error"<<endl;
// exit(1);
// }
// char c[80];
// cin.getline(c,80);//最多提取80个字符,或者遇到默认终止符\n结束
// for (int i=0;c[i]!='\0';i++)
// {
// if (c[i]>=65&&c[i]<=90||c[i]>=97&&c[i]<=122)
// {
// //outfile.put(c[i]);或者
// outfile<<c[i];
// cout<<c[i];
// }
// }
// cout<<endl;
// outfile.close(); //从上面的文件读入字符,将其中的小写字母改写为大写字母在存在f3文件
ifstream infile("f2.dat");
if (!infile)
{
cout<<"openerrr";
exit(1);
}
ofstream outfile3("f3.dat");
if (!outfile3)
{
cout<<"error";
exit(1);
}
char ch;
while (infile>>ch/*infile.get(ch)*/)
{
if (ch>=&&ch<=)
{
ch=ch-;
}
outfile3<<ch;
cout<<ch;
}
cout<<endl;
infile.close();
outfile3.close(); return ; }
二进制文件读写:
主要用istream类的成员函数read 和write来实现 ,成员函数原型:
istream& read(char *buffer,int len);
ostream& write(const char *buffer,int len);
字符指针指向内存中一段存储空间,len是读写的字节数。
#include <fstream>
#include <iostream>
using namespace std;
struct student
{
char name[];
int num;
int age;
char sex;
};
int main()
{
student stu[]={"Li",,,'f',"Fun",,,'f',"Wa",,,'m'};
ofstream outfile("student.dat",ios::binary);//和文件后缀名没关系,即使写成student.txt还是打开乱码,因为编码是自定义的,默认的字符编码解释不了的。
if (!outfile)
{
cerr<<"open erroe";
exit();
}
// for (int i=0;i<3;i++)
// {
// //outfile.write((char *)&stu[i],sizeof(stu[i]));
// outfile.write((char *)(stu+i),sizeof(stu[i]));
// }
//取代for循环,直接一句话
outfile.write((char *)stu,sizeof(stu));
outfile.close(); //读取
ifstream infile("student.dat",ios::binary);
if (!infile)
{
cerr<<"open error";
exit();
}
student stu2[];
infile.read((char*)stu2,sizeof(stu2));
infile.close(); //打印
for (int i=;i<;i++)
{
cout<<stu2[i].name<<endl;
cout<<stu2[i].age<<endl;
cout<<stu2[i].num<<endl;
cout<<stu2[i].sex<<endl; }
return ; }
注意
fstream iofile("student.dat",ios::in|ios::out|ios::binary);
if(!iofile)
{cout<<"open error";
exit(1);} //不知道为何新建一个能输入输出的二进制文件总会出错,二上面例子中新建一个输入输出的文本文件可以。
随机访问二进制数据文件
利用seekg(),seekp等成员函数移动指针,随机的访问文件中任意位置上的数据。
举例:(文件读写有两个指针,读文件指针和写指针。)
iofile.seekg(2*sizeof(stu[2]),ios::beg);把输入指针移动到第三个学生数据开头
iofile.read((char *)&stu2[0],sizeof(stu2[0]));
iofile.seekp(2*sizeof(stu[2]),ios::beg);把输出指针移动到第三个学生数据开头
iofile.write((char *)&stu2[0],sizeof(stu2[0]));
C C++ 文件输入与输出的更多相关文章
- C++文件输入和输出
1.引入头文件fstreamfstream头文件定义了用于文件输入的类ifstream和文件输出的类ofstream 2.写文件1)创建一个ofstream对象来管理输出流2)将该对象与文件关联起来3 ...
- python文件输入和输出
1.1文件对象 文件只是连续的字节序列.数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成.1.2文件内建函数open()和file() 内建函数open()的基本语法是: file_ ...
- 网易云课堂_C++程序设计入门(下)_第7单元:出入虽同趣,所向各有宜 – 文件输入和输出_第7单元 - 作业2:编程互评
第7单元 - 作业2:编程互评 查看帮助 返回 提交作业(剩余10天) 完成并提交作业 作业批改 互评训练 互评作业 自评作业 成绩公布 查看成绩 由于在线编程不支持 ...
- Numpy 用于数组的文件输入和输出
将数组以二进制格式保存 np.save 和np.load 是读写磁盘数组数据的两个主要函数.默认情况下,数组是以未压缩的原始二进制格式进行保持在扩展名 为.npy的文件中的 如果文件路径末尾没有扩展名 ...
- C++——输入、输出和文件
一.C++输入和输出概述 1.1.流和缓冲区 C++程序把输入和输出看作字节流.输入时,程序从输入流中抽取字节:输出时,程序将字节插入到输出流中.对于面相文本的程序,每个字节代表一个字符,更通俗地说, ...
- C++_IO与文件5-文件的输入与输出
大多数计算机程序都使用了文件.文件本身是存储在某种设备上的一系列字节. 通常,操作系统管理文件,跟踪它们的位置.大小.创建时间等. 除非在操作系统级别上编程,否则通常不必担心这些事情. 真正需要的是将 ...
- C++_IO与文件4-简单文件的输入与输出
通过键盘输入和屏幕输出被称为是控制台输入/输出: 更广义上讲控制台的输入/输出也是一种特殊的文件输入/输出: 当使用cin进行输入时,程序将输入视为一系列的字节,其中的每个字节都被解释成字符编码: 不 ...
- matlab学习笔记5--低级文件输入输出函数
一起来学matlab-matlab学习笔记5 低级文件输入输出函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等著 感谢张 ...
- python应用(7):输入与输出
如前文,流程是程序的主角,而流程一般都需要处理数据,那数据如何进到流程,而最终处理后的数据又如何表现,这就是流程的输入与输出的问题. 本文介绍流程处理的数据的输入与输出. 流程中的输入,一般都会先保存 ...
随机推荐
- C++ namespace的用法
//namesp.h namespace pers{ const int LEN = 40; struct Person{ char fname[LEN]; ...
- 数据源(HikariCP)
HikariCP 是一个高性能的 JDBC 连接池组件.下图是性能的比较测试结果: 自从看到了这张图,我就对于我之前一直在使用了 c3p0 产生了深深的怀疑,迫切的期望得到对应的数据来优化我的代码. ...
- 【WP8】键盘弹出时控制Frame位置
WP上,当使用TextBox输入文字的时候,键盘会把TextBox向上推一段距离 当编辑第二个TextBox的时候,页面被上推,键盘刚好和TextBox靠在一起 当编辑第一个TextBox的时候,页面 ...
- 【VirtualBox】共享文件夹失效问题
fix: sudo ln -f -s /opt/VBoxGuestAdditions-5.1.20/lib/VBoxGuestAdditions/mount.vboxsf /sbin/mount.vb ...
- Android 虚拟键盘弹出把底部栏顶上去的解决办法
在AndroidManifest中使用ActivityGroup的activity中加上:android:windowSoftInputMode="adjustPan"
- chrome插件开发之调试
https://blog.csdn.net/qustdong/article/details/46046553
- 品鉴同事发来的炸金花的PHP程序代码
今天同事发来了一个炸金花的PHP程序,这个代码实现了两个人通过各自的三张牌进行权重计算,得到分数进行比较得到谁的牌大,我觉得里面还有一些问题,代码如下: <?php /** 每张牌的分值为一个2 ...
- C++ mysql 乱码
C++读mysql数据库中的中文显示出来的是乱码 在连接到数据库后加上这么一句 mysql_query(pMYSQL, "SET NAMES GB2312"); 或者 mysql_ ...
- php 安装rabbitmq扩展无报错版
需要安装rabbitmq-c,rabbitmq-c是一个用于C语言的,与AMQP server进行交互的client库.下载了v0.5.2版本(https://github.com/alanxz/ra ...
- RF--执行案例时动态传入参数方法
通过在运行界面的设定-v 参数值来动态传入: