C++写的文本颠倒代码

(过程:从名为“in.txt”中读取信息,颠倒输出到“out.txt”中。)

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
35
36
37
38
39
40
41
42
43
44
45
/* C++ */
#include <iostream>
#include <fstream>
#include <ctime>
int main()
{
clock_t start, finish;
start = clock();
long len = -1L; /* 与文件头的距离 */
char tmp, last; /* tmp记录当刻值,last记录上一个值 */
bool tag = false, flag = false; /* tag用于标记第二个'\n',flag用于标记汉字 */
std::ifstream inp( "in.txt", std::ios::in );
std::ofstream oup( "out.txt", std::ios::out );
if ( inp.fail() == true )
{
std::cout << "please make sure the file is exist !" << std::endl; exit( 1 );
}
inp.seekg( len, inp.end ); /* 移至文件尾 */
len = (long) inp.tellg(); /* 获取文件尾距离头的距离 */
std::cerr << "A total of " << len + 1 << " bytes\nOpening file ..."; /* 显示文件大小 */
while ( len >= 0 )
{
inp.seekg( len--, inp.beg ); /* 测试结果是:从文件头开始寻址,比从当前位置ios::cur寻址快一点. */
tmp = inp.get();
if ( tmp == 10 && !(tag ^= 1) )
continue; /* windows中‘\t’和‘\r’重复 if(flag) */
{
oup << tmp << last; /* 汉字输出 */
flag = false;
} else if ( tmp < 0 )
{
last = tmp;
flag = true;
} else
oup << tmp; /* ASCII表内值输出 */
}
inp.close();
oup.close();
finish = clock();
system( "out.txt" ); /* 打开输出文件 */
std::cerr << "\nOpen the file successfully\n";
oup.open( "run_time.txt", std::ios::app );
oup << "Time: " << (finish - start) / 1000.0 << " (s)-use beg" << std::endl; /* 在文件中写入操作时间 */
return(0);
}

注:

代码中使用从文件头开始寻址,比从当前位置ios::cur寻址快一点的原因是由于磁盘的读写方式决定的。因为,所有的寻址搜索都是文件头开始的,cur寻址先从文件头进行寻址到cur位置
再从cur寻址到偏移地址,beg从文件头通过偏移地址得到地址,所以beg要快。

//为了验证这种读写方式,请看我写的一个简单的测试过程:

为了使影响检测的因素简单化,我把上面代码中一些无关部分删除。

测试代码:

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
35
#include <iostream>
#include <fstream>
#include <ctime>
int main()
{
clock_t start, finish;
start = clock();
long len = -1L;
std::ifstream inp( "in.txt", std::ios::in );
std::ofstream oup( "out.txt", std::ios::out );
inp.seekg( len, inp.end );
len = (long) inp.tellg();
std::cerr << "A total of " << len + 1 << " bytes\nOpening file ...";
while ( len >= 0 )
{
/******使用ios::cur寻址的代码********/
oup << (char) inp.get();
inp.seekg( -2L, inp.cur ); len--;
/*******使用ios::beg寻址的代码********
* inp.seekg(len--,inp.beg);
* oup<<(char)inp.get();
************************************/
}
inp.close();
oup.close();
finish = clock();
FILE*p1 = fopen( "run_time.txt", "a+" );
fprintf( p1, "Time: %.3lf (s)-use cur\n", (double) (finish - start) / 1000.0 ); /* 牵扯格式的我比较喜欢用C */
fclose( p1 );
system( "run_time.txt" );
std::cerr << "\nOpen the file successfully\n";
return(0);
}

然后,使用一个1000000字节的文本文件测试(测试数据生成代码在最后面),测试结果如下:
测试结果

前三个是使用ios::beg寻址的,后三个是使用ios::cur寻址的,很明显前者要快一点。所以印证了我前面所说的。

附测试数据生成代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
freopen( "out.txt", "w", stdout );
long n = 1000000;
while ( n-- )
{
putchar( 65 + rand() % 26 ); /* 大写字母 */
}
return(0);
}

测试环境皆为Win XP professional,VC++6.0

本文为原创,转载请遵守本站版权声明

更新于:2015年10月12日 10:10