- 大体思路:
IO流打开文本文件,循环读取,把非空行入队列,读取完之后清空文件,把队列内容重新写回文件。 - 纠结过:
当文件结尾几行是空行的时候就处理不了。
- 看到文件结尾标志是EOF,其实是16进制0xFF,想把这个直接写入到想终止的地方,这样就能造成文件结束了。但是尝试了很久,未果。
- 想使用截断函数,发现WindowsAPI有提供,unistd.h也有提供函数,但是没成功。未果。
效果
处理之前:
处理之后:
算是测试用例吧:
- 开头有空行
- 一行空行
- 连续几行空行
- 结尾空行
代码:
rm_BlankLine.cpp
#include<iostream>
#include<fstream>
#include<regex>
#include<string>
#include<cstdlib>
#include<deque>
using namespace std;
/*
*删除文本文件的空行
*
*/
int rm_BlankLine(string file){
fstream targetFile(file,fstream::in | fstream::out);
string line;//作为读取的每一行
string temp;//作为缓存使用
deque<string> noBlankLineQueue;//双向队列,只在队首和队尾操作时性能较好
//判断文件是否打开
if(!targetFile){
cerr << "Can't Open File!" << endl;
return EXIT_FAILURE;
}
//记录文件开始位置
auto StartPos = targetFile.tellp();
//循环读取判断文件的空行并放入队列
while(getline(targetFile,line)){
cout << targetFile.tellg() << endl;;
if(line.empty()){
cout << "此行为空" << endl;
}else{
cout << "上一行是空行" << endl;
noBlankLineQueue.push_back(line);
}
}
targetFile.close();
//使用ofstream打开再关闭文件是为了清空源文件
ofstream emptyFile(file);
emptyFile.close();
//重新打开文本文件
fstream target(file,fstream::out | fstream::in);
if(!target){
cerr << "Can't Open File" << endl;
}
//获取队首和队尾
auto begin = noBlankLineQueue.begin();
auto end = noBlankLineQueue.end();
//遍历双向队列中的元素
//并写回文件
while(begin != end){
temp = *begin;
cout << temp << endl;
target << temp << endl;
++begin;
}
target.close();
return EXIT_SUCCESS;
}
int main(){
rm_BlankLine("te.txt");
}