按行逆向複製一個文件

這是一個面試題,要求把類似下面的一個文件(a.txt)的行逆向複製到另一個文件(anew.txt)。如下,

a.txt:

------begin------
a
b
c
d
e
f
------end------

anew.txt
------end------
f
e
d
c
b
a
------begin------

下面是我寫的程序,利用了遞歸算法。算法描述在代碼後面

//C program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZ 1024

void reverse_line_copy(FILE *fp_in, FILE *fp_out)
{
	if (fp_in!=NULL && feof(fp_in)==0) 
    {
		char buf[SIZ] = {0};
		int first_line = (ftell(fp_in)==0L) ? 1 : 0;    //the first_line
		int last_line = 0;      //the last_line

		fgets(buf, SIZ, fp_in);  //read a line to buf
		last_line = feof(fp_in)!=0;

		reverse_line_copy(fp_in, fp_out);   //遞歸
		if (first_line && !last_line && strlen(buf)!=0)  //first_line
			buf[strlen(buf)-1] = '\0';
		else if (last_line && !first_line)  //last_line
			buf[strlen(buf)] = '\n';
		fputs(buf, fp_out);
	}
}

int main(void)
{
	FILE *file_in, *file_out;
	if ((file_in=fopen("a.txt", "r"))==NULL) {
		perror("fopen error");
		exit(1);
	}
	if ((file_out=fopen("anew.txt", "w+"))==NULL) {
		perror("fopen error");
		exit(1);
	}
	reverse_line_copy(file_in, file_out);

	fclose(file_in);
	fclose(file_out);
	return 0;
} 

算法描述:

(1)本算法的主體是函數reverse_line_copy

(2)遞歸過程是:現在我要把1~n行字符逆向複製到別的文件中,那麼我假定:如果能先把2~n行逆向複製到別的文件中,然後再把第一行復制到文件後,那麼這個任務就算完成了。同理,逆向複製2~n行用的辦法正是最開始的算法,從而形成遞歸調用。

(3)reverser_line_copy函數,先讀取第一行,文件指針fp_in隨即跳到第二行,然後遞歸調用reverser_line_copy函數,最後把第一行復制進文件中。完成!

依據這個遞歸算法,也可以用C++程序實現,稍微簡單一點!雖說程序簡單,但下面這個程序也揭示了一個大家不太關注的細節。

//C++ program
#include <iostream>
#include <fstream>
#include <deque>
#include <string>
using namespace std;

void reverse_line_copy(ifstream &inf, ofstream &outf);
int main()
{
	ifstream file_in("a.txt");
	if (!file_in) {
		cerr << "can't open file \"" << "a.txt" << "\"" << endl;
		exit(1);
	}
	ofstream file_out("anew.txt");
	if (!file_out) {
		cerr << "can't open file \"" << "anew.txt" << "\"" << endl;
		exit(1);
	}
	reverse_line_copy(file_in, file_out);
	file_in.close();
	file_out.close();
	return 0;
}

void reverse_line_copy(ifstream &inf, ofstream &outf)
{
	string aline;
	if (getline(inf, aline))
	{
		bool last_line = inf.eof() ? true : false;
		reverse_line_copy(inf, outf);
		if (last_line)
			outf << aline;
		else
			outf << aline << endl;
	}
}

上面這段C++程序之所以簡單一些,是因爲:

C程序裏的讀一行的函數fgets()返回的字符串裏包含行末的換行符;而C++程序裏的getline()不返回行末的換行符。


又鑑於C++提供的方便的流操作和容量可擴展的容器,下面又提供了一個C++程序的順序實現算法。

//C++ program
#include <iostream>
#include <fstream>
#include <deque>
#include <string>
using namespace std;

int main()
{
	ifstream file_in("a.txt");
	if (!file_in) {
		cerr << "can't open file \"" << "a.txt" << "\"" << endl;
		exit(1);
	}
	deque<string> file_deque;
	string aline;
	while (file_in.good()) {
		getline(file_in, aline);
		file_deque.push_back(aline);
	}
	file_in.close();

	ofstream file_out("anew.txt");
	if (!file_out) {
		cerr << "can't open file \"" << "anew.txt" << "\"" << endl;
		exit(1);
	}
	while(!file_deque.empty()) {
		if (file_deque.size()==1)
			file_out << file_deque.back();
		else
			file_out << file_deque.back() << endl;
		file_deque.pop_back();
	}

	file_out.close();
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章