zoukankan      html  css  js  c++  java
  • 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();
    }


  • 相关阅读:
    scrapy中selenium的应用
    Django的锁和事务
    redis
    【leetcode】187. Repeated DNA Sequences
    【leetcode】688. Knight Probability in Chessboard
    【leetcode】576. Out of Boundary Paths
    【leetcode】947. Most Stones Removed with Same Row or Column
    【leetcode】948. Bag of Tokens
    【leetcode】946. Validate Stack Sequences
    【leetcode】945. Minimum Increment to Make Array Unique
  • 原文地址:https://www.cnblogs.com/lvlang/p/10586462.html
Copyright © 2011-2022 走看看