上篇的“约定”

对应的题目是《C++ IO》

1
2
3
4
5
6
7
8
9
10
11
12
假定给定一个文件来读,我们将在文件的末尾写一个新行,该行包含每一行开头的相对位置(即偏移量)。
例如一个文件:
abcd
efg
hi
j
经过程序修改之后的文件:
abcd
efg
hi
j
5 9 12 14

答案如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
//首先,安全的打开文件
fstream addFile;
addFile.open("1.txt" , fstream::ate | fstream::out | fstream::in);//将标记至于文件尾
if(!addFile)
{
cerr<<"the file is error!"<<endl;
}
//addFile<<"\n";
fstream::pos_type mark = addFile.tellp(); //因为要写入文件嘛
string line;
addFile.seekp(0 , fstream::beg);
string::size_type size = 0;
while(getline(addFile , line) )//while (addFile && addFile.tellg() != end_mark && getline(addFile, line)) :这是标准答案的做法,咱确实没人家想的周到啊
{
fstream::pos_type sign = addFile.tellp();
size += (line.size() + 1);
addFile.seekp(0 , fstream::end);
addFile<<size<<" ";
addFile.seekp(sign);
}
addFile.clear();
addFile.seekp(0 , fstream::end);
addFile<<"\n";
addFile.close();
return 0;
}

/*解释: 首先,用ate方式打开文件,将文件的标记定位到文件尾

其次,开始初始设置:

这段程序的核心部分将循环通过文件,一次一行,循环过程中记录每一行的 相对位置。循环应该读文件的内容,直到但不包含正在增加的保存行偏移量的那 一行。因为将对文件进行写,所以不是在遇到文件结束符时停止循环,相反,应 在到达原始输入结束处结束循环。要做到这一点,必须首先记住原来文件结束符 的位置。

再次,主循环处理:

先检测文件是否处于有效状态,这显然是必须的,防止输入造成的错误,接着,判断文件是否读到 了原始文件的文件尾(如果超出,则无意义),然后才是每次循环取一行,计算并叠加偏移量, 当然,你的适时的添加输出格式。 当然,最主要的还是中间的sign,因为你每次输入的时候都必须定位到文件尾 ,而你读入文件却得从原先读取的下一字节开始读,这两个位置显然不同,所以便要在

1
2
fstream::pos_type sign = addFile.tellp();
fstream::pos_type sign = addFile.tellp();

这两条语句中间进行操作啦

最后,善后啦,你懂得

1
2
3
4
5
6
7
8
9
10
11
*/
初始文件
![](http://i.imgur.com/9Qegk0O.jpg)
经过处理:
![](http://i.imgur.com/WJmDqEe.jpg)
哈哈,要是觉得不对,可以上机试试哦

热评文章