C++文件操作

这里说C++风格的文件操作,也就是<fstream>库里面的使用(ifstream/ostream)。

(1)删除某一特定行

思想:首先你需要有方法找到你要删除的那一行是哪一行,然后逐一遍历文件的每一行,并用一个临时string变量(网上有另一个方法是新开一个暂存文件)存储,判断如果是要是删除的那一行,就不要把该行存到string临时变量中,也就是跳过该行,继续遍历到文件尾不能get到内容为止。此时,已经把文件里面除了要删除那行的其他所有行都暂存了,于是把原文件所有内容清空(ios::trunc),清空完之后再把临时string变量存储的东西再放入文件,关闭文件,就达到了删除特定行的效果。

void dele()
{
	cout << "请输入要删除的域名" << endl;
	string domain;
	cin >> domain;
	string temp,d,h,p,pp;
	string _filename = filename + ".txt";
	ifstream infile(_filename);
	int t = find(domain);
	if (t != -1)
	{
		getline(infile, pp);
		temp += pp + "
";
		int count = countLines();
		for (int i = 2; i <= count; i++)
		{
			if (i != t)
			{
				get_content(i, d, h, p);
				//infile >> d >> h >> p;
				temp += d + " " + h + " " + p + "
";
			}
		}
		infile.close();
		//remove(_filename.c_str());//先删除原文件
		ofstream outfile(_filename, ios::trunc);//ios::trunc打开一个文件,然后清空内容
		//cout << temp << endl;
		outfile << temp;
		outfile.close();
		cout << "删除成功" << endl;
	}
	else
	{
		infile.close();
		cout << "未找到相应的记录!" << endl;
		dele();
	}
	key_manage();
}



这里获取每一行的内容我是把功能封装成一个特定的函数get_content了,方便项目其他地方的操作。

const bool get_content(int line,string &domain,string &domain_hash,string &password)//line表示获取第几行的域名+内容
{
	if (line <= 0)
	{
		return false;
	}
	string _filename = filename + ".txt";
	//ifstream infile(_filename,ios::in);//ios:in表示以只读方式打开文件
	ifstream infile(_filename,ios::in);
	if (infile.fail())
	{
		cout << "打开文件失败!" << endl;
		return false;
	}
	int count = countLines();
	int i = 1;
	string temp;
	if (line>count)
	{
		cout << "超出行数" << endl;
		infile.close();
		return false;
	}
	while (i < line)//移动文件指针
	{
		getline(infile, temp);
		i++;
	}
	infile >> domain >> domain_hash >> password;//注意这里是读取下一行!所以上面要在line-1就停止
	infile.close();
	return true;
}



另外,C++文件操作里面打开方式很多样,比如打开的时候添加附加参数能实现更多地功能,比如下面的参数表示用只读方式打开文件:

ifstream infile(_filename,ios::in);//ios:in表示以只读方式打开文件


又如这样打开时直接把文件指针定位到文件尾,然后在文件最后新开一行存储内容:

void fileInput(string domain, string domain_hash, string encryPass)
{
	string _filename = filename + ".txt";
	ofstream outfile(_filename, ios::app); //ios::app 添加到文件尾;ios::ate 把文件标志放在末尾而非起始
	outfile << domain << " " << domain_hash << " " << encryPass << endl;
	outfile.close();
}


关于打开参数这里有篇别人的博客供详细参考:

点击打开链接


(2)计算文件内容总行数:

<pre name="code" class="cpp">int countLines()
{
	ifstream infile(filename+".txt");
	if (infile.fail())
	{
		cout << "打开文件失败!" << endl;
		abort();
	}
	int count = 0;
	string temp;
	while (getline(infile, temp, '
'))
	{
		count++;
	}
	infile.close();
	return count;
}

(3)找文件里的内容:

int find(string domain)
 {
 	int count = countLines();
	for (int i = 2; i <= count; i++)
	{
		string d, h, p;
		bool test = get_content(i, d, h, p);
		if (test)
		{
			if (domain == d)
				return i;
		}
	}
	return -1;//找不到就返回-1
}
 

我这里是按照域名从第二行(因为第一行存的是别的东西)开始找,匹配到就返回所在行的下标。


(4)替换文件内容:

跟删除差不多的操作,也是记录所在行,但是替换的话是要把包括该行也记录下来,只不过记录的内容要替换成新的,然后也是清空文件再放临时变量的内容进去:

void modify()
{
	cout << "请输入要修改密码的相应域名" << endl;
	string domain;
	cin >> domain;
	string _filename = filename + ".txt";
	ifstream infile(_filename);
	int t = find(domain);
	if (t != -1)
	{
		cout << "请输入新密码" << endl;
		string newPass;
		cin >> newPass;
		string key = get_key();
		string newPassword = AES_Encryption(newPass, key);//把新密码拿去加密
		string d, h, p, temp, pp;
		getline(infile, pp);
		temp += pp + "
";
		int count = countLines();
		for (int i = 2; i <= count; i++)
		{
			get_content(i, d, h, p);
			if (i != t)
			{
				temp += d + " " + h + " " + p + "
";
			}
			else// i == t
			{
				temp += d + " " + h + " " + newPassword + "
";
			}
		}
		infile.close();
		//remove(_filename.c_str());//先删除原文件
		ofstream outfile(_filename, ios::trunc);//ios::trunc打开一个文件,然后清空内容
												//cout << temp << endl;
		outfile << temp;
		outfile.close();

	}
	else
	{
		infile.close();
		cout << "未找到相应的记录!" << endl;
		modify();
	}
	key_manage();
}


原文地址:https://www.cnblogs.com/lvlang/p/10586462.html