这里说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 + "\n"; 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 + "\n"; } } 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(); }
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; }
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, '\n')) { 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 + "\n"; int count = countLines(); for (int i = 2; i <= count; i++) { get_content(i, d, h, p); if (i != t) { temp += d + " " + h + " " + p + "\n"; } else// i == t { temp += d + " " + h + " " + newPassword + "\n"; } } 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(); }