Newsgroup: it.comp.lang.c++
Titolo: Scansione Dir

Ciao a tutti,
ho letto un libro di c++ e ora voglio applicare quello che ho studiato.
Ovviamente sono molto confuso e ho molti dubbi ma questo non è un problema.
Devo fare una scansione di una directory ma non ho la più pallida idea 
di come fare, quindi ho cercato in rete e ho trovato questo codice (in 
fondo alla pagina)
Voi che ne pensate? Può andare per un principiante?
Se si ho alcune domande da farvi sul codice
#include <io.h> è una libreria c o c++?
#define DIR "c:"
è un tipo di variabile d'ambiente?
ho cercato senza successo queste due funzioni
_findfirst() e_findnext() su
http://www.cppreference.com/
http://www.cplusplus.com/reference/
quello che ho capito che hanno una relazione diretta con
#include<io.h> e la scansione della dir
di più non so. Fatemi un pò di chiarezza.
Il comando struct serve per avere la possibilità di immagazzinare dati 
di tipo diverso.
struct _finddata_t c_file;
a cosa serve di preciso _finddata_t se lo elimino compilatore inizia a 
segnare errori in varie parti del codice.
Ciao
Lele
--------------------------------
#include <iostream>
#include <string>
#include <io.h>
using namespace std;
#define DIR "c:"
int rec_dir_list(string path) {
   static int count = 0;
   struct _finddata_t  c_file;
   long fh;
   string t_path = path;
   t_path += "\\*.*";
   if((fh=_findfirst(t_path.c_str(),&c_file)) != -1)
     while(_findnext(fh, &c_file) == 0)
       // ignore '.' and '..'
       if(strncmp(
c_file.name
, ".", 1) != 0
          && strncmp(
c_file.name
, "..", 2) != 0) {
         if((c_file.attrib & _A_SUBDIR) == _A_SUBDIR) {
           rec_dir_list(path + "\\" + 
c_file.name
);
           cout << "DIR: " << path << "\\" << 
c_file.name
 << endl;
           count++;
         }
       }
   return count;
}
int main() {
   cout << "There are " << rec_dir_list(DIR)
        << " sub directories\n";
   return 0;
}
---------------------------------

 è un tipo di variabile d'ambiente?
No, è un'istruzione per il preprocessore: definizione di una costante
letterale stringa, per la precisione. Se vuoi programmare in C/C++ fai
bene a studiare cosa siano le #define.

 bene a studiare cosa siano le #define.
Ok allora mi andrò a leggere cos'è #define.
Esiste un "qualcosa" in stile msdn per il c++ consultabile off-line? 
Meglio se in italiano.
Un altra cosa, lavoro sia su sistemi Win che Linux almeno per adesso 
vorrei concentrami su codice che vada bene su entrambi gli OS.
Grazie per il tuo interesse.
Lele

 vorrei concentrami su codice che vada bene su entrambi gli OS.
Allora, per il caso specifico, userai l'API POSIX. Alcuni compilatori
come mingw la supportano. Un buon front-end per mingw è, per esempio,
Code::Blocks.

 a cosa serve di preciso _finddata_t 
È il nome di un tipo. La keyword 'struct' in questo caso è opzionale. (Non
lo è in C.)
Max

 Code::Blocks.
Utilizzo Eclipse c++ sia su Win che Linux.
Ciao
Lele

...dimenticavo
Max M. mi consiglia di installare le librerie boost tu che ne pensi.

Ciao Max M.,
sto cercando di capire che cosa sia e come si usa la libreria boost.
Quando avrņ capito te lo farņ sapere.
grazie
Lele

 poi il resto cerco di farlo io.
Eccoti un programmino semplice semplice che usa le API posix per leggere 
una dir (disponibile su win se usi mingw e sempre su sistemi linux o mac):
#include <dirent.h>
#include <iostream>
int main(int argc, char *argv[])
{
     if (argc != 2) return 0;
     if (DIR *dir = opendir(argv[1])) {
         while (dirent *ent = readdir(dir))
	        std::cout << ent->d_name << "\n";
// la struttura dirent contiene anche la tipologia del file oltre che il 
nome
         closedir(dir);
     }
}
Compila, come vedi sia per windows che per linux (in questo caso sto 
usando un crosscompiler x la versione windows).
gabry@nevada:/tmp$ i586-mingw32msvc-g++ -o d.exe d.cpp
gabry@nevada:/tmp$ g++ -o d d.cpp

 Quando avrņ capito te lo farņ sapere.
Non ti consiglio di usare boost, e` una libreria che richiede notevoli 
conoscenze di C++, usa le api posix di cui ti ho mandato un esempio 
nella mail precedente (opendir/readdir).
Bye,
  Gabry

 [...]
Manlio Perillo

 liscio...
Che io sappia sull'uso di Boost con i compilatori CodeGear (ex
Borland) c'e' solo questo: 
http://bcbboost.sourceforge.net/
Ma non ci troverai niente di specifico su Boost.Filesystem. Fino a
qualche versione fa di Boost era abbastanza usabile anche se solo
compilata staticamente per dei motivi che non ricordo. Cosa sia
cambiato di recente non lo so.
Ciao,
Nicola

 conoscenze di C++, [...]
Beh, certamente le librerie di Boost contengono astrazioni e costrutti
sofisticati e difficili da comprendere e padroneggiare per il neofita (e
spesso anche per l'esperto), però contengono anche funzionalità molto
comode e facili da usare. (La stessa cosa, del resto, vale per la libreria
standard.)
Nel caso in questione, ad esempio, il codice per scorrere una directory è
molto semplice:
  directory_iterator end;
  for( directory_iterator = i( path ); i != end; ++i )
  {
      cout << i->path().filename() << endl;
  }
Max

 comode e facili da usare.
E' vero e a Lele sicuramente deve interessare sapere che esistono
librerie già pronte, ma queste risultano utili più che altro in ambito
professionale (o comunque quando certe nozioni di base sono ben
chiare). Se lui è un neofita della programmazione (come mi è sembrato
di intuire) fa prima bene a farsi le ossa affrontando le questioni a
un livello un po' più basso.

Ciao Gabriele Greco,
ci lavoro qualche giorno e poi mi faccio vivo.
Grazie per il tuo interesse.
lele

Ciao Andrea Laforgia.
sono un supernubbio, queste librerie boost sono adatte o no per una 
persona che ha voglia di farsi le ossa?
Ciao
Lele

 
Come non detto. Sappiamo con certezza che *non* ci saranno nel prossimo
Standard. Saranno, invece, presumibilmente aggiunte in un successivo
Technical Report, fra qualche anno. (Vi consiglio di leggere gli articoli
indicati da Davide Quack qualche giorno fa. Ne vale la pena.)
Max

Ciao Gabriele Greco,
grazie al tuo codice sono riuscito a fare qualcosa di funzionante anche 
se estremamente elementare.
#include <dirent.h>
#include <iostream>
using std::cout;
using std::endl;
int main()
{
	DIR *directory = opendir("C:/");
	while (dirent *scansione = readdir(directory)){
		cout << scansione->d_name << endl;
	}
	closedir(directory);
}
Non ho capito come ottenere una scansione delle subdirectory, puoi darmi 
una ditta?
Deduco che la parola chiave dirent serve solo per accendere alla 
gestione delle dir giusto?
Prendo in esame il tuo codice:
Perché questa istruzione? sarà sempre diverso da 2
if (argc != 2) return 0;
if (DIR *dir = opendir(argv[1]))
So che i puntatori e gli array grosso modo sono la stessa cosa, ovvero
una sequenza di memoria occupata ma non ho capito il come mai di argv[1]
Puoi darmi un chiarimento?
Ciao
Lele

 Puoi darmi un chiarimento?
argv è un array che contiene i parametri passati nella riga di comando.
Semplicemente il suo sorgente apre un percorso non prefissato
nell'eseguibile ma proveniente dalla riga di comando, ovviamente prima
controllando se ci sono i parametri.
Enrico

 Funzione ricorsiva?
Meglio stack. Personalmente avendo una classe stack che funziona
decorosamente quando sono nel mondo imperativo preferisco usare quello.
*Specie* per un principiante, che così impara e si leva molte grane per
il futuro.
Poi suggerisco sempre, a scopo didattico, di prendere confidenza anche
con qualche linguaggio funzionale. Ma questa è un altra storia.
-- 
E la necessaria conclusione a tutto è Python.

 controllando se ci sono i parametri.
if (DIR *dir = opendir(argv[1]))
Quindi argv[1] serve solo per non creare un errore in fase di 
compilazione anche se non esiste nessun percorso.
Ciao
Lele

 if (argc != 2) return 0;
controlla se "argc" (che è il "contatore" dei parametri passati a riga
di comando) è diverso da due (nel caso in cui non si è specificato un
percorso argc diventa 1 perché l'unico argomento presente in argv è il
nome dell'eseguibile stesso).
Enrico

 nome dell'eseguibile stesso).
Ok un contatore ma come avanza? Non c'è un argc++ o simili.
Non sono ancora riuscito a capire come fare la scansione delle subdirectory.
Grazie per l'enorme disponibilità.
Lele