• 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();
    }


  • 相关阅读:
    条款27: 如果不想使用隐式生成的函数就要显式地禁止它
    条款26: 当心潜在的二义性
    条款23: 必须返回一个对象时不要试图返回一个引用
    条款22: 尽量用“传引用”而不用“传值”
    条款21: 尽可能使用const
    【转】我的算法学习之路
    【转】基于Linux下的TCP编程
    条款十九: 分清成员函数,非成员函数和友元函数
    【c++】C语言中volatile关键字的作用
    innerHTML,innerText,outHTML,outText区别
  • 原文地址:https://www.cnblogs.com/lvlang/p/10586462.html
Copyright © 2020-2023  润新知