C++写的文本颠倒代码

2013年9月23日 01:02

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

/* 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要快。

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

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

测试代码:

#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寻址的,很明显前者要快一点。所以印证了我前面所说的。

附测试数据生成代码:

#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