2009-08-13 15 views
16

Czy istnieje gładki sposób na glob w C lub C++ w systemie Windows?Globbing w C++/C, na Windows

Np. Program myprogram.exe * .txt wysyła do mojego programu listę ARGV, która zawiera ... ARGV [1] = *.txt.

Chciałbym móc mieć funkcję (nazwijmy ją readglob), która pobiera ciąg znaków i zwraca wektor ciągów znaków, z których każdy zawiera nazwę pliku.

W ten sposób, jeśli mam pliki a.txt b.txt c.txt w moim katalogu, a readglob pobiera argument *.txt, zwraca powyższą listę plików.

//Prototype of this hypothetical function. 
vector<string> readglob(string); 

Czy takie istnieją?

Odpowiedz

23

Linków setargv.obj (lub wsetargv.obj) i argv [] zostanie globbed dla ciebie podobny do tego, jak pociski Unix zrobić:

nie mogę ręczyć jak to działa.

+0

Strasznie bezkompromisowo, ale to proste i działa. –

+4

Nie musi to być platforma wieloplatformowa, ponieważ tylko Win32 ma ten problem! Świetna rada. –

+2

Po prostu wypróbowałem to sam. Działa jak mistrz. Nie może być łatwiejsze. –

0

Ehw. Musiałem wprowadzić coś takiego w ANSI C około 15 lat temu. Zacznijmy od procedur opendir/readdir ANSI, jak sądzę. Globs nie są dokładnie takie, jak RegEx, więc będziesz musiał zaimplementować własne filtrowanie.

+0

Zgodnie z http://stackoverflow.com/questions/883594/microsoft-visual-studio-opendir-and-readdir-how opendir/readir nie ma w Visual Studio. –

+0

Drat! muszą to być POSIX, a nie ANSI. Cokolwiek się stało z warstwą Win NT POSIX ??? – Roboprog

2

mówiono o posiadaniu go w systemie Boost :: files, ale zostało ono zrzucone na korzyść użycia boost :: regex.

dla Win32 specyficznego (MFC) można użyć klasy CFileFind

+0

To jest bummer. Wykonanie szybkiego testu przy użyciu cl & #including afx.h powoduje błąd połączenia z nowym. +1 za link, ale nie chcę jeść wieczorem, pracując nad tym, żeby MFC działało dla mnie. –

+0

Wygląda na to, że w przypadku plików innych niż MFC możesz użyć FindFirstFile i przyjaciół, aby zrobić to z prostym kodem win32. –

+0

MFC jest głównie wrapperami wokół wywołań win32, nie pamiętam FindFirstFile(), teraz wszystko do mnie wraca. –

1

Nie może być lepszy sposób teraz, ale ostatni raz miałem do czynienia z tym problemem skończyło się na tym Henry Spencer's regex library statycznie połączony do mojego programu (jego biblioteka jest licencjonowana na BSD), a następnie stworzyłem klasę wrapper, która przekształciła wyrażenia globalne użytkownika w wyrażenia regularne, aby były podawane do kodu regex. Jeśli chcesz, możesz wyświetlić/pobrać klasę opakowania here.

Po wprowadzeniu tych części, ostatnią rzeczą do zrobienia jest odczytanie katalogu i podanie nazwy każdego wpisu w dopasowanej funkcji, aby sprawdzić, czy pasuje do wyrażenia, czy nie. Nazwy plików, które pasują, dodajesz do swojego wektora; te, których nie odrzucasz. Odczytanie katalogu jest dość proste przy użyciu funkcji DOS _findfirst() i _findnext(), ale jeśli chcesz mieć ładniejszy interfejs C++, mam klasę portable wrapper również dla tego ...

3

Jest to bardzo specyficzne dla systemu Windows. Nie wiem, jak to napisać, aby być wieloplatformowym. Ale użyłem tego w programach Windows i działa dobrze dla mnie.

// Change to the specified working directory 
string path; 
cout << "Enter the path to report: "; 
cin >> path; 
_chdir(path.c_str()); 

// Get the file description 
string desc; 
cout << "Enter the file description: "; 
cin >> desc; 

// List the files in the directory 
intptr_t file; 
_finddata_t filedata; 
file = _findfirst(desc.c_str(),&filedata); 
if (file != -1) 
{ 
    do 
    { 
    cout << filedata.name << endl; 
    // Or put the file name in a vector here 
    } while (_findnext(file,&filedata) == 0); 
} 
else 
{ 
    cout << "No described files found" << endl; 
} 
_findclose(file); 
+0

nie używaj znaczników pre/code, zamiast tego podświetl kod i kliknij przycisk z 1/0 na nim. Sprawi, że pojawi się jako kod. –

+0

Dzięki, Evan. Po raz pierwszy umieściłem kod w odpowiedzi. Oczywiście ... –

+0

+1 za kod; Wybrałem odpowiedź Michaela, ponieważ jest o wiele prostsza. :-) –