Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 23
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    133

    [C++] Lettura file in una cartella

    Ho un piccolo problema. Volevo sapere come si poteva fare ad accedere a tutti i file presenti in una cartella in un programma scritto in C++. Diciamo che ho un'applicazione e voglio che essa sia applicata a tutti i file in una determinata cartella, ma voglio che lo faccia automaticamente. Esistono delle API o qualcosa di simile che mi permettono di "ciclare" su ogni file presente in una cartella? Come si fa?
    Grazie mille

  2. #2
    Sistema operativo?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    133
    Windows XP. Comunque, ho trovato le istruzioni per usare FindFirstFile, FindNextFile e FindClose. Il problema è quasi risolto. Ho solo ancora due piccoli problemi.
    Il primo argomento di FindFirstFile è di tipo LPTCSTR, e non riesco a modificarla come tale. Esempio:
    Diciamo che voglio accedere automaticamente ai file di tipo *.txt di una cartella (contenuta nella cartella del mio programma), quindi da riga di comando voglio che si inserisca solo il nome della cartella, ad esempio

    C:\>...\mioProgramma nomeCartella

    e automaticamente mi accede al primo file *.txt dentro nomeCartella. Quindi, essendo nomeCartella = argv[1], se potessi aggiungere la stringa "\*.txt" ad argv[1], potrei poi passare argv[1] a FindNextFile come primo argomento e ottenere l'HANDLE per il primo file nella cartella nomeCartella. Come posso aggiungere quel pezzo di stringa a argv[1]?!
    Secondo problema. Con [HANDLE].cFileName posso recuperare il nome del primo file, poichè ritorna una stringa. Però, a questo punto, se uso questa stringa per aprire il file con quel nome con il costruttore ifstream myfile(NomeDelFile), mi da errore "no matching function for call to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::string&)' " ...presumo che ifstream voglia un puntatore a stringa o qualcosa di simile? Dov'è il problema?

    Pseudocodice d'esempio

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    argv[1].append("\*.txt"); //operazione non valida...operazione equivalente?!

    LPCTSTR nomeFolder = argv[1];


    hFind = FindFirstFile(nomeFolder, &FindFileData);

    string nomeFile = FindFileData.cFileName;
    ifstream myfile (nomeFile); //ERRORE sul tipo passato alla funzione. Eppure con
    //ifstream myfile("nomeFile.txt") lo apre...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da McKracken
    Come posso aggiungere quel pezzo di stringa a argv[1]?!
    Per combinare un path io in genere uso PathCombine:

    codice:
    CHAR szSearch[MAX_PATH];
    
    PathCombine (szSearch, argv[1], "*.txt");
    L'unica accortezza: includere <shlwapi.h> e linkare con shlwapi.lib.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    Il tuo codice contiene alcuni errori, tra cui i seguenti:
    • richiami un metodo "append" inesistente - argv non è fatta di string, ma di semplici puntatori a const char;
    • a tale metodo inesistente tra l'altro passi una stringa che usa una sequenza di escape non corretta ("\*.txt"); probabilmente intendevi "\\*.txt";
    • inoltre per costruire il percorso di ricerca supponi che il percorso che l'utente ha specificato sia valido e non termini con un backslash (\);
    • costruisci inutilmente un oggetto string (basta passare FindFileData.cFileName a funzioni che si aspettano una stringa);
    • richiami un costruttore della classe ifstream che non esiste (devi crearla e poi richiamarne il metodo open)
    • tra l'altro ci passi direttamente un oggetto string (se un costruttore del genere esistesse si aspetterebbe un const char *, per ottenere il quale dovresti richiamare nomeFile.c_str());
    • non termini la ricerca (non richiami FindClose).

    Ecco del codice corretto:
    codice:
    #define VC_EXTRALEAN //Servono solo le API principali
    #include <iostream>
    #include <fstream>
    #include <windows.h>
    #include <shlwapi.h>
    //Nota: perché questo codice funzioni va linkato anche con shlwapi.lib; in VC++ si può ottenere tale effetto anche con un #pragma non standard
    #ifdef _MSC_VER
    #pragma comment(lib,"shlwapi.lib")
    #endif
    //...
    using namespace std;
    int main(int argc, char * argv[])
    {
        //Ricerca dei file txt nella cartella indicata
        WIN32_FIND_DATA fd;
        char searchString[MAX_PATH];
        if (!PathIsDirectory(argv[1]))
        {
        	cerr<<"Il percorso indicato non esiste.\n";
        	return 1;
        }
        //Costruisce la stringa di ricerca
        if (PathCombine(searchString,argv[1],"*.csv")==0)
        {
        	cerr<<"Impossibile creare la stringa di ricerca.\n";
        	return 2;
        }
        clog<<"Ricerca dei file txt in \""<<argv[1]<<"\"...\n";
        //Ricerca il primo file che corrisponde ai criteri
        HANDLE hFind=FindFirstFile(searchString,&fd);
        if (hFind==INVALID_HANDLE_VALUE)
        {
        	cout<<"Impossibile trovare file txt nella cartella specificata.\n";
        	return 3;
        }
        do
        {
        	ifstream is;
        	is.open(fd.cFileName, ios::out); //eventualmente cambia ios::out in quello che deve essere
        	//... fa quello che deve fare ...
        	is.close();
        } while(FindNextFile(hFind,&fd)); //Continua a cercare fino a quando non ci sono più files
        //Termina la ricerca
        FindClose(hFind);
    }
    ---EDIT---
    Maledizione, arrivo tardi.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2005
    Messaggi
    133
    Tnx...scusa l'ignoranza. Uso il dev C++, come posso linkare staticamente la libreria? Basta passarlo nei parametri?

    Invece per l'altro problema? Se ho un tipo string, come lo converto in un const char * ?! Grazie...

  7. #7
    Originariamente inviato da McKracken
    Tnx...scusa l'ignoranza. Uso il dev C++, come posso linkare staticamente la libreria? Basta passarlo nei parametri?
    Non so, credo che tu debba aggiungerla nelle proprietà del progetto.
    Invece per l'altro problema? Se ho un tipo string, come lo converto in un const char * ?!
    Richiama il suo metodo c_str() che ti restituirà un const char *.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da McKracken
    Tnx...scusa l'ignoranza. Uso il dev C++, come posso linkare staticamente la libreria? Basta passarlo nei parametri?
    Il Dev-C++ non ha shlwapi.h/shlwapi.lib. Usa un ambiente di sviluppo più serio: Visual C++ Express.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  9. #9
    Il Dev-C++ non ha shlwapi.h/shlwapi.lib
    "Dev-C++" HA shlwapi.h e shlwapi.lib

    Shlwapi.h inizia così:

    codice:
    #ifndef _SHLWAPI_H
    #define _SHLWAPI_H
    #if __GNUC__ >=3
    #pragma GCC system_header
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #ifndef _OBJC_NO_COM
    #include <objbase.h>
    #include <shlobj.h>
    #endif
    
    #ifndef WINSHLWAPI
    #define WINSHLWAPI DECLSPEC_IMPORT
    #endif
    
    #define DLLVER_PLATFORM_WINDOWS	0x00000001
    #define DLLVER_PLATFORM_NT	0x00000002
    
    #define URL_DONT_ESCAPE_EXTRA_INFO 0x02000000
    #define URL_DONT_SIMPLIFY	0x08000000
    #define URL_ESCAPE_PERCENT	0x00001000
    #define URL_ESCAPE_SEGMENT_ONLY	0x00002000
    #define URL_ESCAPE_SPACES_ONLY	0x04000000
    #define URL_ESCAPE_UNSAFE	0x20000000
    #define URL_INTERNAL_PATH	0x00800000
    #define URL_PARTFLAG_KEEPSCHEME	0x00000001
    #define URL_PLUGGABLE_PROTOCOL	0x40000000
    #define URL_UNESCAPE		0x10000000
    #define URL_UNESCAPE_HIGH_ANSI_ONLY 0x00400000
    #define URL_UNESCAPE_INPLACE	0x00100000
    
    #ifndef RC_INVOKED
    #include <pshpack1.h>
    In ogni caso, se proprio vuoi usare MinGW, butta via Dev-C++ e passa a Code::Blocks.

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da pallinopinco
    "Dev-C++" HA shlwapi.h e shlwapi.lib
    Il Dev-C++ 4 no, non li l'ha. Se in una versione più recente ci sono, meglio.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.