Có cách nào để đọc một tập tin ngược, từng dòng một, mà không cần phải đi qua các tập tin từ đầu để bắt đầu đọc ngược?Đọc một tệp ngược?
Trả lời
Theo nhận xét, một lựa chọn có thể (khá đơn giản) sẽ được đọc các dòng vào một vector
.Ví dụ:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::ifstream in("main.cpp");
if (in.is_open())
{
std::vector<std::string> lines_in_reverse;
std::string line;
while (std::getline(in, line))
{
// Store the lines in reverse order.
lines_in_reverse.insert(lines_in_reverse.begin(), line);
}
}
}
EDIT:
Theo jrok 's và Loki Astari' s ý kiến, push_back()
sẽ hiệu quả hơn nhưng các dòng sẽ được theo thứ tự tập tin, lặp đi lặp lại như vậy ngược lại (reverse_iterator
) hoặc std::reverse()
sẽ là cần thiết:
std::vector<std::string> lines_in_order;
std::string line;
while (std::getline(in, line))
{
lines_in_order.push_back(line);
}
Bạn có thể sử dụng 'std :: reverse' sau khi đọc xong hoặc chỉ lặp lại với' reverse_iterator'. – jrok
@jrok, mã chèn ở mặt trước của vectơ khi nó đứng, do đó các dòng sẽ được sắp xếp theo thứ tự ngược lại, do đó không có dạng đảo ngược nào được yêu cầu .. Nếu 'push_back' được sử dụng, thì có, sử dụng một dạng ngược lại . – hmjd
Im sẽ đoán rằng di chuyển tìm kiếm vào mặt sau của tập tin và sau đó lặp đi lặp lại chuyển tiếp sẽ tốt hơn hiệu suất khôn ngoan? – mezamorphic
Câu trả lời ngắn gọn là không. Tuy nhiên, bạn có thể sử dụng hàm seek() để di chuyển con trỏ đến nơi bạn muốn. Sau đó đọc() một số dữ liệu từ điểm đó. Nếu bạn biết rõ cách quản lý bộ đệm, thì nó sẽ khá nhanh vì bạn có thể đọc và lưu trữ dữ liệu và sau đó tìm kiếm (các) ký tự dòng mới trước đó. Hãy vui vẻ với \ r \ n mà sẽ được đảo ngược ...
- Cập nhật: một số xây dựng trên các thuật toán tốt -
Đây không phải là mã hợp lệ, nhưng nó sẽ cho bạn một ý tưởng về những gì tôi đang cố gắng để nói ở đây
tập đọc:
int fpos = in.size() - BUFSIZ;
char buf[BUFSIZ];
in.seek(fpos);
in.read(buf, BUFSIZ);
fpos -= BUFSIZ; // repeat until fpos < 0, although think of size % BUFSIZ != 0
// now buf has characters... reset buffer position
int bpos = BUFSIZ - 1;
Bắt chuỗi:
// first time you need to call the read
if(bpos == -1) do_a_read();
// getting string
std::string s;
while(bpos >= 0 && buf[bpos] != '\n') {
s.insert(0, 1, buf[bpos]);
--bpos;
}
// if bpos == -1 and buf[0] != '\n' then you need to read another BUFSIZ chars
// and repeat the previous loop...
// before leaving, skip all '\n'
while(bpos >= 0 && buf[bpos] == '\n') {
--bpos;
}
return s;
Để dễ dàng với '\ r', bạn có thể có thẻ đầu tiên biến tất cả '\ r' thành '\ n'. Nếu không, tất cả các thử nghiệm của '\ n' cũng cần phải kiểm tra cho '\ r'.
Bạn có thể giải thích chi tiết về điểm đệm không? – mezamorphic
@ user1107474: "từng dòng" chỉ là vấn đề diễn giải các byte \ n \ n' thành dòng mới. Nếu bạn đọc ngược byte, và giải thích các byte dòng mới cho mình, bạn chắc chắn có thể đọc dòng ngược. Nó không chỉ là chức năng tiêu chuẩn. – MSalters
Một lưu ý nhỏ ở đây ... s.insert (0, 1, char) là SLOW. Nếu bạn muốn tăng tốc, bạn sẽ muốn lưu điểm kết thúc (bpos trước khi vào trong khi đó) và điểm bắt đầu (bpos sau một khoảng thời gian) và thêm chuỗi đó vào kết quả cùng một lúc. –
Mở tệp để đọc, gọi
fseek()
để tìm cách kết thúc của tập tin, sau đó gọiftell()
để có được độ dài của tập tin. Ngoài ra, bạn có thể nhận được độ dài tệp bằng cách gọi sốstat()
hoặcfstat()
Phân bổ con trỏ đệm đến kích thước tệp thu được ở # 1, ở trên.
Đọc toàn bộ tệp vào bộ đệm đó - bạn có thể sử dụng
fread()
để đọc toàn bộ tệp trong một lần phát (giả sử tệp đủ nhỏ).Sử dụng một con trỏ char khác để truyền tệp từ đầu đến đầu bộ đệm.
Giả sử các tập tin có thể dễ dàng phù hợp với bộ nhớ, đây là một giải pháp tốt, dễ dàng. –
Sử dụng memory-mapped file và quay lại. Hệ điều hành sẽ trang trong các phần cần thiết của tập tin theo thứ tự ngược lại.
Đó cũng là một ý tưởng, mặc dù thường xuyên ánh xạ một tệp không chính xác về phía trước (Đặc biệt là lần đầu tiên!) –
Hơi phiên bản cải tiến sẽ là thế này: -
1) Tìm cách cuối cùng-1 vị trí
2) Nhận vị trí cuối cùng 1
3) Đọc char và in nó;
4) tìm kiếm 2 pos trở lại;
5) lặp lại 3 & 4 cho last-1
lần;
ifstream in;
in.open("file.txt");
char ch;
int pos;
in.seekg(-1,ios::end);
pos=in.tellg();
for(int i=0;i<pos;i++)
{
ch=in.get();
cout<<ch;
in.seekg(-2,ios::cur);
}
in.close();
- 1. Đọc một tệp văn bản ngược trong C
- 2. Làm thế nào để giữ dấu gạch chéo ngược khi đọc từ một tệp?
- 3. Đọc một tệp .pdb
- 4. Đọc dòng trước trong một tệp python
- 5. đọc một tệp trong python
- 6. Java: Đọc một tệp vào một mảng
- 7. Cách đọc tệp từ đầu đến cuối (theo thứ tự ngược) trong Java?
- 8. Đọc tệp văn bản thành một mảng
- 9. Đọc từ một tệp gzip trong python
- 10. Đọc một tệp văn bản trong java
- 11. Đọc dữ liệu từ một tệp plist
- 12. Đọc một tệp nhị phân với python
- 13. Đọc đồng thời một Tệp (java preffered)
- 14. Đọc một tệp Excel trong PHP
- 15. Đọc một dòng tệp theo dòng C#
- 16. Đọc một dòng tệp theo dòng VB.NET
- 17. JQuery.getJSON() đọc một tệp cục bộ
- 18. Đọc một dòng tệp theo dòng
- 19. đọc/ghi một đối tượng vào tệp
- 20. Đọc lại một tệp mở Python
- 21. đọc một phần của tệp bằng iostreams
- 22. Mở và đọc một tệp với askopenfilename
- 23. Đọc một tệp tin thuộc tính Maven
- 24. Đọc một tệp MIDI bằng Python
- 25. chưa đọc một tệp trong C++
- 26. Tạo Trình đọc scala từ một tệp
- 27. Đọc dữ liệu CSV từ một tệp
- 28. Đa luồng một tệp lớn đọc
- 29. Cách đọc một tệp (hoặc stdin) theo dòng trong Python không chờ đọc toàn bộ tệp
- 30. Đọc một dòng cụ thể của một tệp
Bạn có thể đọc các dòng của tệp thành 'vectơ' và ngược lại. – hmjd
@hmjd Đây phải là câu trả lời, IMO. – jrok