Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Vláďa J 13. 05. 2012, 22:35:45

Název: Výpis adresářů a souborů v C++
Přispěvatel: Vláďa J 13. 05. 2012, 22:35:45
Zdravím,

dneska jsem se začal učit programovat v C++ a tak trochu tápu. Po hodině marnýho hledání jsem se rozhodl, že se radši zeptám.

Pro potřeby mýho programu (snažím se při učení alespoň vyprodukovat něco užitečnýho) potřebuju získat výpis podadresářů a souborů. Našel jsem následující kód:

Kód: [Vybrat]
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int
main (void){
    DIR *dp;
    struct dirent *ep;   
    dp = opendir ("./");
    if (dp != NULL){
        while (ep = readdir (dp))
            puts (ep->d_name);
        (void) closedir (dp);
    }
    else
        perror ("Couldn't open the directory");   
    return 0;
}

V podstatě to dělá to, co potřebuju. Akorát ještě musím projít rekurzivně všechny adresáře a neumím zjistit, jestli je něco adresář nebo soubor. Našel jsem, že struktura dirent by mohla mít položku d_type, ale minimálně na Windows s MinGW to nefunguje.
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: kocour_easy 14. 05. 2012, 00:23:15
man stat a kontrolovat polozku st_mode prikladem makra S_IFDIR

struct stat st;

if (stat(ep->d_name, &st) == 0) {
  if (S_ISDIR(st.st_mode)) {
      .... // directory
  } 
}
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Ales Hakl 14. 05. 2012, 02:51:56
A pro vylozene rekurzivni prohledavani existuji funkce ftw() (pripadne nftw()) (u kterych by se dalo asi cekat, ze budou vsude, kde je opendir/readdir), pripadne trochu rozumnejsi rodina funkci fts_open(), fts_read(), fts_close()..., ktere ovsem nejsou v POSIXu (pochazeji z BSD, na Solarisu nejsou, da se cekat, ze v mingw a interixu jsou)
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: asd 14. 05. 2012, 08:18:37
Ked uz to C++ tak by som odporucil kniznicu Boost File System http://www.boost.org/doc/libs/1_49_0/libs/filesystem/v3/doc/index.htm (http://www.boost.org/doc/libs/1_49_0/libs/filesystem/v3/doc/index.htm).
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Vláďa J 15. 05. 2012, 09:31:33
kocour_easy> Díky, tohle je přesně to, co jsem potřeboval. Na Boost File System jsem také koukal, ale mi přijde trochu jako kanonem na vrabce.

Ale narazil jsem na další problém, spíš teda nejasnost. Potřebuju názvy souborů a adresářů uložit do pole, to si potom seřadit a dál to používat. Doteď jsem progrqamoval jenom v interpertovanych jazycích a tam to nebyl vůbec žádnej problém. Ale pokud to chápu dobře, tak v C si musím nejdřív říct, kolik paměti budu potřebovat. Ale jak to udělat, když to dopředu nevím? V C++ jsem koukal, že třeba string už nepotřebuje dopředu vědět, jak bude dlouhý.

Jak to tedy udělat správně? Napadlo mě udělat si pole pointerů a těma ukazovat na jednotlivý řetězce. Je to správnej přístup? Jak to prakticky udlat?

Stačí mě trochu nakopnout, zbytek už si najdu nebo vymyslím. Díky.
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: poustevnik 15. 05. 2012, 10:57:56
Ale pokud to chápu dobře, tak v C si musím nejdřív říct, kolik paměti budu potřebovat. Ale jak to udělat, když to dopředu nevím?
Stačí mě trochu nakopnout, zbytek už si najdu nebo vymyslím. Díky.
v C můžeš dynamicky alokovat paměť, o které nevíš při kompilaci, kolik jí bude, pomocí funkce malloc(). nezapomeň to na konci uvolnit pomocí funkce free()
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: tommy 15. 05. 2012, 11:03:33
Použij boost::filesystem http://www.boost.org/doc/libs/1_49_0/libs/filesystem/v3/doc/index.htm#Documentation (http://www.boost.org/doc/libs/1_49_0/libs/filesystem/v3/doc/index.htm#Documentation). Je to rychlé, platformně nezávislé a zdokumentované (na rozdíl od některých jiných knihoven v boostu).
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Vláďa J 15. 05. 2012, 14:38:36
tommy> Určitě na to v budoucnu kouknu, momentálně mi ale zatím funguje to, co potřebuju.

poustevnik> To jsem našel, ale tam to chce, abych při alokaci tý paměti zadal, kolik jí potřebuju. Já to samozřejmě dopředu nevím. Nevím, kolik souborů/adresářů najdu ani jak dlouhý bude jejich jméno. Jak se tohle řeší?
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: edois 15. 05. 2012, 14:54:50
Koukám, že chceš psát v C++, ale píšeš to jako v C. Pokud se chceš opravdu C++ zabývat, začni tím, že si nastuduješ STL (Standard Template Library), konkrétně především kontejnery (std::set, std::list, std::vector, std::map, ...) a algoritmy (std::sort, ...) a potom aspoň základy Boostu.

A tady máš ukázku vylistování adresáře /etc seřazené podle přípony :)

Kód: [Vybrat]
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/lambda/lambda.hpp>
#include <iostream>

int main(int argc, char **argv)
{
    std::vector<boost::filesystem::path> files;

    std::copy(
        boost::filesystem::directory_iterator(
            boost::filesystem::path("/etc")),
        boost::filesystem::directory_iterator(),
        std::back_inserter(files));

    std::sort(files.begin(), files.end(),
        boost::bind(&boost::filesystem::path::extension, boost::lambda::_1)
        < boost::bind(&boost::filesystem::path::extension, boost::lambda::_2));

    BOOST_FOREACH(boost::filesystem::path &file, files) {
        std::cout << file.filename() << std::endl;
    }

    return 0;
}

linkovat s volbou -lboost_filesystem-mt

Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Sten 15. 05. 2012, 15:57:34
Ta ukázka je teda pro začátečníka docela drsná, navíc to není C++11. Ale jo, tak podobně bych to taky napsal :-)
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Vláďa J 15. 05. 2012, 19:40:55
Ve finále to chci slinkovat s Qt knihovnama, takže to určitě bude C++. Ale na tu ukázku koukám jako puk a moc nechápu, co který příkaz dělá.

Znám celkem dobře Python a PHP, kdysi jsem se učil Pascal. Musím se do toho céčka nějak prokousat. Zatím vím jenom to, že C++ umožňuje OOP a obyčejné C ne, v čem jsou další rozdíly jsem zatím moc nepochytil. Ještě asi nejsem v učení tak daleko, abych na to narazil. Zatím se v tom trochu plácám. V podstatě jsem něco psal, abych pochopil hlavní principy Céčka, pochytil syntaxi a naučil se zkompilovat program. Každopádně pokud někdo víte o nějakym dobrym zdroji informací o programování v C++, sem s ním.
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: nou 15. 05. 2012, 21:21:56
no ak sa chces ucit Qt tak by som pouzil na prechadzanie filesytemu prave to Qt. ale este predtym by si sa mal zamerat na zaklady C++ ako su struktury, triedy, metody, dedenie, new, delete. STL kontajnery, vstup vystup s iostream a potom by som zacal to Qt s ktorym si vybavis ten suborovy system. inak silne odporucam kupit nejaku knihu. C++ je dost zlozity jazyk na to aby sa dal naucit z internetovych tutorialov ktore nemaju taku kvalitu.
Název: Re:Výpis adresářů a souborů v C++
Přispěvatel: Vláďa J 15. 05. 2012, 21:54:02
Knihu by to samozřejmě chtělo, ale já si to hlavně vždycky potřebuju prakticky vyzkoušet. Ale už se malinko začínám orientovat. Po prvotním zděšení z céčka už jsem pochopil, že v C++ existuje typ string, můžu proměnný deklarovat i uprostřed programu, existuje typ vektor a další věci, bez kterých bych se asi těžko obešel (respektive dalo by to neúměrně práce). Věci jako metody, třídy, dědění atd. znám z Pythonu, to bude předpokládám analogický, jenom se naučím jinou syntaxi (teda doufám :-)).

Qt knihovny používám už dlouho díky PySide. Ale Python zatím třeba na Androidu neběží, takže musím psát v C++. Tak se to snažím naučit...