c++读取写入数据
前言
对学习C/C++感兴趣的小伙伴可以看看这篇文章哦:C/C++教程
本章主要详解C/C++对文件的所有常见方法汇总
先要明白一个概念,即几乎在所有编程语言中,文件处理都是一个非常重要的模块
因为文件可以实现对数据大量且长久的存储
一、文件处理过程
无论什么编程语言,处理文件的过程都可以分为以下三步:
- 打开文件
- 操作文件
- 关闭文件
所以当我们操作文件的时候,请务必牢记这三点,因为该逻辑几乎是所有语言通用的,只不过具体实现细节略有差异
二、C处理文件
首先来看C中处理文件的方式,因为C是面向过程的语言,所以使用起来较为繁琐,你需要记住很多函数
而这些函数所在的头文件为:
1
| #include<cstdio> //或者#include<stdio.h>均可
|
同时需要注意的是:
C语言库中的函数,很多都存在安全隐患,就会存在一个相应的安全函数,一般对应的安全函数名称都是在原函数后添加_s
后缀
例如:fopen
的安全函数为fopen_s
相比较而言,安全函数会比标准函数使用更繁琐,所以很多情况下我们会习惯于使用标准函数,
但在VS环境下直接使用不安全的函数,会直接报错,编译无法通过,此时就必须要定义对应的宏才能正常使用
而安全函数则无需定义任何宏,可直接使用
具体使用哪一种看个人习惯,官方推荐使用安全函数
1.打开文件
首先是打开文件的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| FILE* fopen( const char * _FileName, const char * _Mode );
errno_t fopen_s( FILE** _Stream, const char * _FileName, const char * _Mode );
|
两种函数的使用区别:
1 2 3 4 5 6 7 8 9
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","r"); if (file == NULL) { return -1; } }
|
1 2 3 4 5 6 7 8 9
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","r"); if (err != 0) { return -1; } }
|
对于mode
参数,有如下选择:

2.读文件
然后就是文件操作中的读:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| //标准函数: size_t fread( void* _Buffer, //读取到的内容存放空间 size_t _ElementSize, //每次读多少个字节 size_t _ElementCount, //读多少次 FILE* _Stream //文件标识符 ); //返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1
//安全函数: size_t fread_s( void* _Buffer,//读取到的内容存放空间 size_t _BufferSize, //第一个参数指示的缓存区大小 size_t _ElementSize,//每次读多少个字节 size_t _ElementCount,//读多少次 FILE* _Stream //文件标识符 ); //返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1
|
两者使用区别:
1 2 3 4 5 6 7 8 9 10 11
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","r"); if (file == NULL) { return -1; } char buf[0xFF]; size_t size=fread(buf,1,100, file); }
|
1 2 3 4 5 6 7 8 9 10 11
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","r"); if (err != 0) { return -1; } char buf[0xFF]; size_t size=fread_s(buf,sizeof(buf),1,100,file); }
|
除了上面最基本的读文件数据函数,还有一些其它读操作的函数:
fgetc
:从文件中读取一个字符
1 2 3 4
| int fgetc( FILE* _Stream );
|
1 2 3 4 5 6 7 8 9 10
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","r"); if (file == NULL) { return -1; } char c=fgetc(file); }
|
fgets
:从文件中读取一个字符串
1 2 3 4 5 6
| char* __cdecl fgets( char* _Buffer, int _MaxCount, FILE* _Stream );
|
使用:
1 2 3 4 5 6 7 8 9 10 11
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","r"); if (file == NULL) { return -1; } char buf[0xFF]; fgets(buf,0xFF,file); }
|
fscanf
:按格式从文件中读取指定内容,与scanf
函数类似
1 2 3 4 5
| int fscanf( FILE* const _Stream, char const* const _Format, ... )
|
使用:
1 2 3 4 5 6 7 8 9 10 11 12
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","r"); if (file == NULL) { return -1; } int d; char buf[0xFF]; fscanf(file,"%d %s",&d,buf); }
|
fscanf_s
:fscanf
的安全函数,作用相同
1 2 3 4 5
| int fscanf_s( FILE* const _Stream, char const* const _Format, ... )
|
使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","r"); if (err != 0) { return -1; } int b; char buf[0xFF]; fscanf_s(file,"%d %s",&b,buf,sizeof(buf)); fclose(file); }
|
4.写文件
文件操作主要就两个,上面说了读,下面就是写了:
标准函数:
1 2 3 4 5 6
| size_t fwrite( void const* _Buffer, size_t _ElementSize, size_t _ElementCount, FILE* _Stream );
|
使用:
1 2 3 4 5 6 7 8 9 10 11
| #define _CRT_SECURE_NO_WARNINGS #include<cstdio> using namespace std; int main() { FILE* file = fopen("1.txt","w"); if (file == NULL) { return -1; } char buf[] = "test"; fwrite(buf,1,sizeof(buf),file); }
|
该函数无安全函数
除了最基本的写入函数,还有一些其它的常用写操作函数:
fputc
:向文件中写入一个字符
1 2 3 4
| int fputc( int _Character, FILE* _Stream );
|
使用:
1 2 3 4 5 6 7 8 9 10
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","w"); if (err != 0) { return -1; } int ret=fputc('c',file); }
|
fputs
:向文件中写入一个字符串
1 2 3 4
| int fputs( char const* _Buffer, FILE* _Stream );
|
使用:
1 2 3 4 5 6 7 8 9 10
| int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","w"); if (err != 0) { return -1; } char buf[] = "test"; int ret = fputs(buf,file); }
|
fprintf
:向文件中写入指定格式字符串,与pritnf
函数类似
1 2 3 4 5
| int fprintf( FILE* _Stream, char const* const _Format, ... )
|
使用:
1 2 3 4 5 6 7 8 9 10
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","w"); if (err != 0) { return -1; } fprintf(file,"%d %s",4,"test"); }
|
fprintf_s
:fprintf
的安全函数
与fprintf
没什么区别,不再讲解
5.关闭文件
最后是关闭文件
1 2 3
| int fclose( FILE* _Stream );
|
使用:
1 2 3 4 5 6 7 8 9 10
| #include<cstdio> using namespace std; int main() { FILE* file; errno_t err=fopen_s(&file,"1.txt","w"); if (err != 0) { return -1; } fclose(file); }
|
三、C++处理文件
C++使用了面向对象对文件处理进行了封装,所以处理文件会比C方便很多
为了方便使用,C++封装了三个文件操作类
头文件:
1 2
| #include<fstream> using namespace std;
|
代码:
首先是最通用的类fstream
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<fstream> using namespace std; int main() { fstream file; file.open("1.txt",ios::out); char buf[] = "test"; file.write(buf,sizeof(buf)); file<<"666"<<endl; file.close();
file.open("1.txt", ios::app); char buf1[] = "test1"; file.write(buf1, sizeof(buf)); file.close();
file.open("1.txt",ios::in); char buf2[0xFF]; file.read(buf2,0xFF); file.close(); }
|
模式选择:

但既然已经封装成为了类,那么在特定需求下,打开文件这个操作也是可以省略的
c++中读取文件中数据的三种方式以及数据类型转换_
1.逐词读取,用 空格 区分每个词
创建输入流对象infile
打开相应的文件,创建一个字符串data
来存储文件中的数据:
1 2 3 4 5 6
| ifstream infile("data.txt"); string data; while (infile) { infile >> data; cout << "read from file:" << data<<" "; }
|
2.逐行读取,将每行数据读入字符数组中,用 回车换行 区分每行数据
创建输入流对象infile
打开相应的文件,创建一个字符数组data
来存储文件中的数据,此时需要使用getline()
函数来逐行读取文件的数据:
1 2 3 4 5
| ifstream infile("data.txt"); char data[1000]; while (infile.getline(data, 1000) ) { cout << "read from file:" << data << endl; }
|
3.逐行读取,将每行数据读入字符串内,用 回车换行 区分每行数据
创建输入流对象infile
打开相应的文件,创建一个字符串data
来存储文件中的数据,此时需要使用getline()
函数来逐行读取文件的数据:
1 2 3 4 5
| ifstream infile("data.txt"); string data; while (getline(infile, s)) { cout << "read from file:" << data << endl; }
|
这种方式结合C++中数据转换类istringstream
类很容易实现按行读取数据后再按照 空格 分割单个数据。
C++中的数据类型转换类
C++中引入了 istringstream
、ostringstream
、stringstream
这三个类来进行不同类型数据的转换,要使用它们创建对象就必须包含 <sstream>
这个头文件。
istringstream
类用于执行C++风格的串流的输入操作。
istringstream
对象可以绑定一行字符串,然后以空格为分隔符把该行分隔开来。在读取数据文件时可以按行读取数据并存储到字符串中,然后通过istringstream
字符串分割开,并存储到相应类型的变量中。语法格式如下:
1
| istringstream::istringstream(string str);
|
将一个字符串中数字分割开并赋值给double类型的变量:
1 2 3 4 5
| string str = "92 20 120.7"; double num1 = 0, num2 = 0, num3 = 0; istringstream string_to_num(str); string_to_num >> num1 >> num2 >> num3 ; cout << num1 << endl << num2 << endl << num3 ;
|
ostringstream
类用于执行C++风格的串流的输出操作。
ostringstream
对象可以将多种数值转换成字符串,可以用于字符串的合并;
1 2 3 4 5 6 7
| ostringstream os string str = "qwerdf" int i = 6666
os<<str<<i cout<<os.str() os.str("")
|
strstream
类同时可以支持C++风格的串流的输入输出操作。
首先是读文件的类ifstream
:
1 2 3 4 5 6 7 8 9 10 11 12
| #include<iostream> #include<fstream> using namespace std; int main() { ifstream f("1.txt"); char buf[0xFF]; f.read(buf,0xFF); char c=f.get();
char bufLine[0xFF]; f.getline(bufLine,0xFF); }
|
然后是写文件的类ofstream
:
1 2 3 4 5 6 7 8 9
| #include<iostream> #include<fstream> using namespace std; int main() { ofstream f("1.txt"); char buf[0xFF]; f.write("hello world",12); f.put('c'); }
|