首先想到的最笨的辦法就是打開文件,然後遍歷一遍,計算出文件中的行數,然後在從頭開始遍歷文件,在某個位置開始打印從文件中讀出的行。這是一個比較笨的方法,還有一種很巧妙的方法就是應用circular buffer,初次見到這個名稱的人可能感覺很神奇,但是如果知道循環隊列這個概念的話,那麼就不難理解了。如果我們準備打印一個文件的最後n行,我們可以建立一個n+1空間的循環隊列,至於爲什麼是n+1的循環隊列,是爲了表示隊列什麼時候滿,什麼時候是空的。接下來就解決怎麼打印最後n行吧:首先我們把讀出的每行的字符串的首地址放在隊列中,如果隊列已經被填滿了,那麼我們開始進行覆蓋,也就是說第如果隊列用n個空間,那麼當第n+1行到來的時候,我們就把原來存放第一行字符串首地址的隊列某空間用第n+1行的首地址覆蓋掉,依次對之後的行來進行如此的操作,大家很容易發現,到最後隊列中存留下來的就是最後n行的字符串的首地址。
下面給出wikipedia中,講述circular buffer的連接:http://en.wikipedia.org/wiki/Circular_buffer 然後給出我自己寫的代碼:
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
class Queue {
private:
void **elem;
int front, rear;
int size;
public:
Queue(int _size) {
size = _size + 1;
elem = (void**)malloc(size * sizeof(void*));
memset(elem, 0, size * sizeof(void*));
front = rear = 0;
}
Queue() {
free(elem);
}
void enQueue(void *addr);
void deQueue(void **addr);
bool isQueueEmpty();
};
void Queue::enQueue(void *addr) {
if ((rear + 1) % size == front) {
free(elem[front]);
elem[front] = NULL;
front = (front + 1) % size;
}
elem[rear] = addr;
rear = (rear + 1) % size;
}
void Queue::deQueue(void **addr) {
if (rear == front)
return;
*addr = elem[front];
elem[front] = NULL;
front = (front + 1) % size;
}
bool Queue::isQueueEmpty() {
return rear == front;
}
int main(int argc, char *argv[]) {
char temp[100];
Queue q(10);
ifstream fin;
fin.open("test.txt", ifstream::in);
while (fin >> temp) {
int n = strlen(temp);
char *s = (char*)malloc(n + 1);
strcpy(s, temp);
s[n] = '\0';
q.enQueue(s);
}
while (!q.isQueueEmpty()) {
char *s = NULL;
q.deQueue((void**)&s);
cout << s << endl;
free(s);
}
cin.get();
return 0;
}