Ponieważ nie mogę założyć nowego wątku w dziale z językami programowania to postanowiłem napisać tutaj z nadzieją, że ktos to przeniesie gdzie należy.
Moje pytanie dotyczy operacji wejścia/wyjścia na plikach (PC) i brzmi nastepująco: Jak odczytywać plik od końca? O co mi chodzi. Otóż mam plik, który może mieć nawet kilka GB (więc wczytywanie do pamięci odpada). W pliku tym wystepuje pewna fraza nawet kilkaset razy. Mnie interesuje tylko ostatnie jej wystąpienie. Wiem jak czytac plik od początku do końca ale w tym przypadku chciałbym zrobić to w drugą stronę żeby łatwiej znaleźć te frazę. Czy ktoś zna rozwiązanie tego problemu?
[PC] Przeglądanie plików w C
[PC] Przeglądanie plików w C
Life is to short to eject USB safely
Re: [PC] Przeglądanie plików w C
Po pierwsze użył bym fopen64() do dużych plików.
Pod filesize masz rozmiar pliku, a offset ustawiasz pozycje od której chcesz czytać.
Kod: Zaznacz cały
FILE *f;
f = fopen64(filename, "r");
fseek(f, 0, SEEK_END);
filesize = ftell(f);
...
fseek(f, offset, SEEK_SET);
Pod filesize masz rozmiar pliku, a offset ustawiasz pozycje od której chcesz czytać.
Gott weiß ich will kein Engel sein.
Re: [PC] Przeglądanie plików w C
To nie rozwiązuje mojego problemu gdyz nie wiem gdzie w pliku jest faza. Wiem tylko, że występuje kilka razy i potrzebuje jej ostatniego wystapienia
Tutaj jest plik
https://www.dropbox.com/s/ybhhmdnh9sk42 ... o.out?dl=0
W środku wystepuje fraza HF=numerek MP2=numerek. W lini numer 6169 ta fraza występuje ostatni raz.
To samo dotyczy frazy "Dipole moment". W linii 5656 występuje ostatni raz.
Potrzebuje włąśnie te linie wyłuskac i te numerki. O ile samo parsowanie tekstu jest juz banalne to odnalezienie tych "ostatnich" fraz już takie proste dla mnie nie jest. Co jest ważne to pliki te mają różną wielkośc i dane, których szukam nie sa zawsze w takiej samej odległości od końca.
Tutaj jest plik
https://www.dropbox.com/s/ybhhmdnh9sk42 ... o.out?dl=0
W środku wystepuje fraza HF=numerek MP2=numerek. W lini numer 6169 ta fraza występuje ostatni raz.
To samo dotyczy frazy "Dipole moment". W linii 5656 występuje ostatni raz.
Potrzebuje włąśnie te linie wyłuskac i te numerki. O ile samo parsowanie tekstu jest juz banalne to odnalezienie tych "ostatnich" fraz już takie proste dla mnie nie jest. Co jest ważne to pliki te mają różną wielkośc i dane, których szukam nie sa zawsze w takiej samej odległości od końca.
Life is to short to eject USB safely
- mokrowski
- User
- Posty: 190
- Rejestracja: czwartek 08 paź 2015, 20:50
- Lokalizacja: Tam gdzie Centymetro
Re: [PC] Przeglądanie plików w C
Przepis:
1. Czytasz plik od tyłu z użyciem ustawiania pozycji przez lseek() i pamięcią ilości bajtów czytanych od tyłu.
2. Każdy znak przeczytany wstawiasz do tablicy.
3. Jak znajdziesz znak '\n', to w tablicy będzie cała 1 linia.
4. W linii tej szukasz wystąpienia znaków wzorca (u Ciebie "HF=") i zapamiętujesz indeks.
5. Pozycja w pliku to offset z pkt. 1 zsumowany (lub odjęty jeśli liczyć będziesz od tyłu) z indeksem tablicy linii.
6. Uzyskałeś przesunięcie w pliku a dalej... parsujesz już plik jak chcesz/umiesz/potrzebujesz...
1. Czytasz plik od tyłu z użyciem ustawiania pozycji przez lseek() i pamięcią ilości bajtów czytanych od tyłu.
2. Każdy znak przeczytany wstawiasz do tablicy.
3. Jak znajdziesz znak '\n', to w tablicy będzie cała 1 linia.
4. W linii tej szukasz wystąpienia znaków wzorca (u Ciebie "HF=") i zapamiętujesz indeks.
5. Pozycja w pliku to offset z pkt. 1 zsumowany (lub odjęty jeśli liczyć będziesz od tyłu) z indeksem tablicy linii.
6. Uzyskałeś przesunięcie w pliku a dalej... parsujesz już plik jak chcesz/umiesz/potrzebujesz...
,,Myślenie nie jest łatwe, ale można się do niego przyzwyczaić" - Alan Alexander Milne: Kubuś Puchatek
Re: [PC] Przeglądanie plików w C
Ooo. podoba mi się:)
Sprawdzę wieczorem czy dziala. Dziękuję
Sprawdzę wieczorem czy dziala. Dziękuję
Life is to short to eject USB safely
- mokrowski
- User
- Posty: 190
- Rejestracja: czwartek 08 paź 2015, 20:50
- Lokalizacja: Tam gdzie Centymetro
Re: [PC] Przeglądanie plików w C
Masz tu kod:
Jak mówiłem, w trybie komercyjnym pewnie jeszcze bym coś z tym robił ale Ty chciałeś jedynie pomocy.
Kod: Zaznacz cały
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <exception>
#include <regex>
using namespace std;
pair<size_t, string> back_position_and_line(ifstream& file,
size_t file_size, size_t current_position = 0) {
char c;
vector<char> char_vector;
auto position = current_position;
while(position <= file_size) {
position++;
file.seekg(-position, ios::end);
file.get(c);
char_vector.push_back(c);
if (c == '\n' || position == file_size) {
auto line = string(char_vector.rbegin(), char_vector.rend());
line.erase(remove(line.begin(), line.end(), '\n'), line.end());
return { position, line };
}
}
// File size 0 bytes..
return {0, ""};
}
pair<size_t, size_t> get_position_backward(const string& file_path, const string& pattern) {
// Set cursor to end of file, binary, input.
auto file = ifstream(file_path, ios::ate | ios::binary | ios::in );
if(!file.is_open()) {
string throw_msg("File ");
throw_msg += file_path + string(" open error.");
throw logic_error(throw_msg);
}
size_t file_size = file.tellg();
auto pattern_regex = regex(pattern, regex::extended);
smatch sm;
pair<size_t, string> result{};
do {
result = back_position_and_line(file, file_size, result.first);
regex_match(result.second, sm, pattern_regex);
if(sm.position(1) < result.second.length()) {
return {file_size - (result.first - sm.position(1)) + 1, file_size };
}
} while(result.first < file_size);
// No match :-(
return {file_size, file_size};
}
int main(void) {
// matched "HF=2131.33XXXXMP2=-212.3312"
string search_rgxp="^.*(HF=(-?)[0-9]*\\.[0-9].*MP2=(-?)[0-9]*\\.[0-9].*).*$";
auto position = get_position_backward("e-1-h2o.out", search_rgxp);
if(position.first == position.second) {
cout << "No match!" << endl;
exit(0);
}
// Fast and dirty check...
ifstream file = ifstream("e-1-h2o.out");
file.seekg(position.first, ios::beg);
char c;
for(; c != '\n'; file.get(c)) {
cout << c;
}
cout << endl;
}
Jak mówiłem, w trybie komercyjnym pewnie jeszcze bym coś z tym robił ale Ty chciałeś jedynie pomocy.
,,Myślenie nie jest łatwe, ale można się do niego przyzwyczaić" - Alan Alexander Milne: Kubuś Puchatek
Re: [PC] Przeglądanie plików w C
Podoba mnie się ten kod. Chociaż i tak będzie/zostanie przerobiony z powodu, że nie zawsze wystepuje tekst MP2, a i HF lubi sobie różnie inaczej występować. Ale to już jakiś zysk.
W każdym razie wczoraj zanim dostałem dzisiajszą odpowiedź od Ciebie poradziłem sobie tak, że czytam od początku wszystkie HF'y, a nastepnie po zakończeniu czytania pliku biore ostatni wczytany. Ot i się rozwiązało
Podziękował śliczniasto
W każdym razie wczoraj zanim dostałem dzisiajszą odpowiedź od Ciebie poradziłem sobie tak, że czytam od początku wszystkie HF'y, a nastepnie po zakończeniu czytania pliku biore ostatni wczytany. Ot i się rozwiązało
Podziękował śliczniasto
Life is to short to eject USB safely
Wróć do „Pisanie programów w C”
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość