很多时候我们说C++不如Python、Java之类的语言使用简便,这个在某些时候是很客观的。像Python关于文件的操作readline、readlines等函数就可以解决一切。但是“C++”的函数File、fscanf、fprintf等函数真的麻烦又麻烦。其实,我们很多人用的函数属于古老C++或者很多都是C的接口。下面我们就来看一下C++关于文件操作的函数:
关于详细文件(继承关系和函数)的介绍可参考博客:
https://blog.csdn.net/sinat_36219858/article/details/80369255
ifstream:
创建一个文件输入流对象。其构造方式有两种:
1、通过构造函数直接传入需要打开的文件路径。默认打开方式是in。
2、通过空参的构造函数创建对象,调用open函数来进行打开。
//构造函数1
basic_ifstream()
//构造函数2
explicit basic_ifstream(const char *_Filename,
ios_base::openmode _Mode = ios_base::in,
int _Prot = (int)ios_base::_Openprot)
ifstream is("wenben.txt");
ifstream is1();
is1().open("wenben.txt");
getline:
从下面源码中我们可以看出getline的第一个参数是继承自basic_istream的所有类都可以。第二个参数是可以自定义间隔符,只不过默认的是\n。
注意:如果我们需要对某个字符串用getline进行处理的时候,我们需要通过stringstream来进行包装起来,然后可以将stringstream的对象传入getline函数的第一个参数即可。
template<class _Elem,
class _Traits,
class _Alloc> inline
basic_istream<_Elem, _Traits>& getline(
basic_istream<_Elem, _Traits>& _Istr,
basic_string<_Elem, _Traits, _Alloc>& _Str)
{ // get characters into string, discard newline
return (getline(_STD move(_Istr), _Str, _Istr.widen('\n')));
}
template<class _Elem,
class _Traits,
class _Alloc> inline
basic_istream<_Elem, _Traits>& getline(
basic_istream<_Elem, _Traits>& _Istr,
basic_string<_Elem, _Traits, _Alloc>& _Str,
const _Elem _Delim)
stringstream:
需要包含头文件 #include <sstream>
该类可以实现将字符串和数字之间进行转换的操作,同时,string类型的对象可以通过stringstream进行管理,这样就可以代替sprintf函数。
注意:如果字符串之间不是按照空格类进行分割的,那么将出现垃圾数字,或者我们可以通过每次只转换一个数字,清空stringstream来进行处理。
#include<iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc,char *argv[])
{
stringstream ss("123 456");
int a;
int b;
ss >> a >> b;
cout << a << b << endl;
cout<<"hello"<<endl;
system("pause");
return 0;
}
运行结果:
#include<iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc,char *argv[])
{
stringstream ss;
ss << "123";
int a;
int b;
ss >> a;
cout << a << endl;
ss.clear();
ss << "456";
ss >> b;
cout << b << endl;
cout<<"hello"<<endl;
system("pause");
return 0;
}
运行结果:
将字符串插入文本文件中某行的操作:
当我们需要用C++在文本文件中的某行插入一行或某行并删除掉以前的内容时,我们就需要自己写一些函数来实现,其实,通过文件流和getline函数就可以实现这些操作。
#include<iostream>
#include <fstream>
#include <sstream>
using namespace std;
/************************************************************************
本函数是将内容插入到文件中的某行,并且删除掉对应的行的内容
Para1:需要插入的文件名
Para2:需要插入的内容,如果是多行的话请加上\n分隔符,第一个字符必须是\n
Para3:需要在第几行进行插入
Para4:这些内容需要占多少行
************************************************************************/
int insertByLineNumber(string filePath, string insertContent, int insertLine, int gap = 1)
{
if (filePath == "" || insertContent == "" || gap <= 0 || insertLine < 0)
{
return -1;
}
ifstream is(filePath);
if (!is.is_open())
{
cerr << "文件打开失败" << endl;
return -1;
}
string tmp;
string buffer;
int count = 0;
while (getline(is,tmp,'\n'))
{
count++;
if (count == insertLine)
{
buffer += insertContent;
buffer += "\n";
}else if (count > insertLine && count < insertLine + gap)
{
continue;
}
else
{
buffer += tmp;
buffer += "\n";
}
}
is.close();
ofstream os(filePath);
os << buffer;
os.close();
return 0;
}
/************************************************************************/
/* 用来计算一个文件的行数的函数
Para1:传入需要计算行号的文件路径
return:返回的是行数
*/
/************************************************************************/
int calcFileLines(string fileName)
{
if (fileName == "") return -1;
ifstream is(fileName);
if (!is.is_open()) return -1;
int count = 0;
while (getline(is,string(),'\n'))
{
count++;
}
return count;
}
int main(int argc,char *argv[])
{
insertByLineNumber("wenben.txt", "woshinidie", 1);
//cout << lines << endl;
system("pause");
return 0;
}