Oppure

Loading
12/09/20 12:55
AldoBaldo
Siamo dei fenomeni, dai! :k:
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
12/09/20 20:11
Il comando ls e' di unix/linux e non funzionera' col dos (con cui si usa la dir).

Inoltre non si usano i comandi della shell ma le api di Windows per elencare i file e le cartelle in c
Ultima modifica effettuata da 12/09/20 20:27
12/09/20 20:26
AldoBaldo
Certo, di solito uso FindFirstFile(), FindNextFile() e FindClose(). Però la richiesta era posta in un modo che mi ha fatto pensare che deviare su quelle tre funzioni avrebbe solo creato dei problemi a Musical Wrighter.
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
13/09/20 16:16
L'uso della shell e del comando linux in windows evidenziano il fatto che chi scrive non ha idea di quello che fa. Allora è meglio spiegargli che sta sbagliando completamente strada e dirgli come si fa realmente.
13/09/20 20:45
AldoBaldo
Se interverrà nuovamente e vorrà sapere qualcosa delle tre funzioni che ho citato, sicuramente mi farà piacere cercare di dargli una mano (fin dove so arrivare e come so arrivarci).
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
08/10/20 14:52
musical wrighter
Salve rieccomi e chiedo scusa a tutti per la risposta tardiva. In realtà credevo d'aver inviato una risposta a settembre, un giorno o due dopo l'ultimo messaggio di AldoBaldo che invece o il comando invia non lo ha preso crome e nella fretta di chiudere non me ne sono accorto o mi è andata via la connessione nel momento migliore. Fatto sta che ho dovuto formattare il pc quindi sono stato in sti giorni temporaneamente bloccato sul fronte esperimenti di programmazione e quando mi sono nuovamente collegato quì in questo forum ho avuto sta bella sorpresina. Comunque avevo scritto che nei comandi find first file e find next file mi sono già imbattuto e gli ho usati nel mio primo tentativo con quello che sto tentando in c++. Ovvero una sorta di player audio parlante. Che di ogni audio wav presente nella directory dell'exe ne fa uscire un output del nome sia a schermo che vocale e ne riproduce l'audio. Non sono riuscito in questa operazione con find first file e find next file perché gli esempi di codice che ho trovato in siti come stackoverflow non erano molto chiari su come usare questi due metodi per far esplorare all'exe la directory in cui si trova. Da quanto ho capito mi sembravano più esempi di codice per ricercare uno specifico file sapendone il nome o parte del nome. E dunque ho ripiegato sui comandi system. Ma sono comunque aperto ad ogni suggerimento. Sto imparando e l'importante è il risultato. Attualmente mettendo in pratica il suggerimento di Aldo Baldo sono riuscito a realizzare un player funzionante che però genera un file da cui rileggere i nomi dei file wav Se mi sapete dire un modo per buttare i nomi dei wav direttamente in delle stringhe senza usare file testuali come tramite tanto meglio. il codice che vi ho condiviso nel primo messaggio l'ho ampliato in questo modo
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#include <sapi.h>
using namespace std;
#pragma comment(lib,&quot;winmm.lib&quot;)
int main()
{
	system(&quot;dir /b *.wav >\&quot;appunti\&quot;&quot;);
	ifstream appunti(&quot;appunti&quot;);
	ISpVoice* pVoice = NULL;
	if (FAILED(::CoInitialize(NULL)))
		return FALSE;
	HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&amp; pVoice);
	if (SUCCEEDED(hr))
	{
		while (!appunti.eof())
		{
			string brano;
			getline(appunti, brano);
			int cut = brano.size() - 4;
			string nome = brano.substr(0, cut);
			wstring cs(brano.begin(), brano.end()), cv(nome.begin(), nome.end());
cout << nome; hr = pVoice->Speak(cv.c_str(), 0, NULL);
			PlaySound(cs.c_str(), NULL, SND_FILENAME);
}
		cout << &quot;arrivederci&quot;; hr = pVoice->Speak(L&quot;arrivederci&quot;, 0, NULL);
	}
	pVoice->Release();
	pVoice = NULL;
	::CoUninitialize();
appunti.close();
}
il primo era un codice di prova per testare i comandi system. Grazie in anticipo e buona serata a tutti.
P.s a confondermi in origine è stata la più recente power shell di windows. Che a quanto pare adotta alcuni comandi di linux come ls invece di dir
Ultima modifica effettuata da musical wrighter 08/10/20 18:44
aaa
08/10/20 20:49
AldoBaldo
Premessa: quel che propongo NON e' un esempio di come fare o non fare, perché non ho la formazione per dare esempi di sorta. NON è neppure "pappa pronta", perché il mio codice sarebbe con ogni probabilità schifato in qualsiasi ambito scolastico/accademico, essendo un codice un po'... alla come viene, viene. Inutilizzabile. Si tratta solo dell'esito di un'attività di intrattenimento suggeritami dal tuo intervento. Prendilo per quel che è (potrebbero esserci errori anche madornali). Detto questo...

Ho messo insieme una classe che permette di ottenere con UNA RIGA di codice un oggetto che fornisce un elenco dei file presenti in una cartella data (ignorando le sottocartelle, però;).

La classe è molto limitata da una quantità di punti di vista. Per dirne una, in caso di errori si limita sempre allo stesso comportamento - lanciare un'eccezione di tipo bool e valore false. Per dirne un'altra, formula le sue stringhe come array di char (da 1 byte), in stile C.

Se si crea un oggetto così...

ElencoFile ef( "C:\Users\NomeUtente\Desktop" );

...l'oggetto viene "popolato" con un elenco dei percorsi e nomi dei file contenuti nella cartella del Desktop di NomeUtente.

Se lo si crea così...

ElencoFile ef;

...l'oggetto viene "popolato" con un elenco dei percorsi e nomi dei file contenuti nella working directory (cartella corrente).

Una volta creato l'oggetto, preferibilmente includendone la creazione in un blocco try/catch per intercettare le eventuali eccezioni di tipo bool, si può conoscere la quantità dei file contenuti nell'elenco con una chiamata a ef.TotaleFile() e si può accedere ai singoli percorso+nome di ogni file con chiamate a ef.NomeFile(indice) purché "indice" sia un valore compreso tra 0 e il totale dei file meno uno. E' anche possibile abbinare un oggetto già esistente a una nuova cartella, con ef.AcquisisciElencoDaCartella().

file main.c di esempio

#include <cstdio>
#include "elencofile.h"

int main() {
    try {
        ElencoFile ef; // elenca i file presenti nella working directory

        for( unsigned int i=0; i<ef.TotaleFile(); ++i )
            printf( "%s\n", ef.NomeFile(i) );

        return 0;
    } catch( ... ) {
        puts( "Errore!" );
        return 1;
    }
}


file elenco_file.h

#ifndef ELENCOFILE_H
#define ELENCOFILE_H

#include <windows.h>
#include <cstdlib>
#include <cstring>

class ElencoFile {
    public:
        ElencoFile( const char *cartella = NULL );
        virtual ~ElencoFile();
        ElencoFile(const ElencoFile& other);
        ElencoFile& operator=(const ElencoFile& other);

        bool AcquisisciElencoDaCartella( const char *cartella );
        unsigned int TotaleFile( void ) const { return tf; }
        const char *NomeFile( unsigned int indice ) const;

    protected:

    private:
        char **ef;       // ef: elenco file
        unsigned int tf; // tf: totale file
        size_t dd;       // dd: dimensioni dati

        char *DuplicaPercorso( const char *percorso );
        bool AnalizzaContenutoCartella(
            const char *cartella, unsigned int *qFile, size_t *dDati );
        char **CreaElencoDaCartella(
            const char *cartella, unsigned int qFile, size_t dDati );
};

#endif // ELENCOFILE_H


file elenco_file.cpp

#include "elencofile.h"

ElencoFile::ElencoFile( const char *cartella ) {
    ef = NULL;
    tf = 0;
    dd = 0;

    if( !AcquisisciElencoDaCartella(cartella) ) throw false;
}

ElencoFile::~ElencoFile() {
    if( ef ) delete[] ef;
}

ElencoFile::ElencoFile(const ElencoFile& other) {
    ef = NULL;
    tf = 0;
    dd = 0;
    *this = other;
}

ElencoFile& ElencoFile::operator=(const ElencoFile& rhs) {
    if (this == &rhs) return *this; // handle self assignment

    if( rhs.ef ) {
        void *tmp = malloc( rhs.dd );
        if( NULL == tmp ) throw false;
        memcpy( tmp, rhs.ef, rhs.dd );
        if( ef ) free( ef );
        ef = (char**)tmp;
        tf = rhs.tf;
        dd = rhs.dd;
    }

    return *this;
}

bool ElencoFile::AcquisisciElencoDaCartella( const char *cartella ) {
    char *dupPercCart = NULL;
    bool ok = false;

    if( (dupPercCart=DuplicaPercorso(cartella)) ) {
        unsigned int tfTmp = 0;
        size_t ddTmp       = 0;

        if( AnalizzaContenutoCartella(dupPercCart,&tfTmp,&ddTmp) ) {
            char **efTmp = CreaElencoDaCartella( dupPercCart, tfTmp, ddTmp );

            if( NULL != efTmp ) {
                if( ef ) free( ef );
                ef = efTmp;
                tf = tfTmp;
                dd = ddTmp;
                ok = true;
            }
        }

        free( (void*)dupPercCart );
    }

    return ok;
}

const char *ElencoFile::NomeFile( unsigned int indice ) const {
    if( ef && indice<tf )
        return ef[indice];
    else return NULL;
}

// privata
char *ElencoFile::DuplicaPercorso( const char *percorso ) {
    char *buff = NULL;

    if( NULL==percorso ) {
        DWORD dimBuff = GetCurrentDirectory( 0, NULL );
        if( (buff=(char*)calloc(dimBuff+4,sizeof(*buff))) ) {
            GetCurrentDirectory( dimBuff, buff );
            memcpy( buff+dimBuff-1, "\*.*", 5 );
        }
    }
    else {
        size_t l = lstrlen( percorso );
        if( (buff=(char*)malloc(l+5)) ) {
            memcpy( buff, percorso, l );
            memcpy( buff+l, "\*.*", 5 );
        }
    }

    return buff;
}

// privata
bool ElencoFile::AnalizzaContenutoCartella(
    const char *cartella, unsigned int *qFile, size_t *dDati ) {
    if( !cartella || !qFile || !dDati ) return false;

    size_t lNomeCartella = lstrlen(cartella)-3;
    WIN32_FIND_DATA fd = {0};
    HANDLE hnd = NULL;

    *qFile = 0;
    *dDati = 0;

    hnd = FindFirstFile( cartella, &fd );

    if( INVALID_HANDLE_VALUE != hnd ) {
        if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
            while( FindNextFile(hnd,&fd) ) {
                if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
                    *dDati += sizeof(char*)+lNomeCartella+lstrlen(fd.cFileName)+1;
                    ++(*qFile);
                }
            }
        }

        FindClose( hnd );
        return true;
    }

    return false;
}

// privata
char **ElencoFile::CreaElencoDaCartella(
    const char *cartella, unsigned int qFile, size_t dDati ) {
    if( !cartella ) return NULL;

    void *dTmp = calloc( dDati, 1 );
    if( !dTmp ) return NULL;
    
    // Lo scopo della gran confusione creata con una pletora di puntatori e cast
    // nelle prossime righe, e' inserire tutti i percorsi+nomi dei file in un
    // unico blocco di memoria al quale sia possibile accedere come ad un comune
    // array di stringhe C. Inutilmente complicato? Puo' darsi. Pasticciato?
    // Puo' darsi. Pero' sembra funzionarea a dovere. :)
    
    size_t lPercorso = lstrlen(cartella)-3;
    size_t dimPtr = sizeof(char*);
    void *y = dTmp;
    void *x = ((void*)(((size_t)dTmp)+qFile*dimPtr));
    unsigned int i=0;

    WIN32_FIND_DATA fd = {0};
    HANDLE hnd = FindFirstFile( cartella, &fd );

    if( INVALID_HANDLE_VALUE != hnd ) {
        if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
            while( FindNextFile(hnd,&fd) && i<qFile ) {
                if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
                    size_t lNomeFile = lstrlen(fd.cFileName);
                    memcpy( y, &x, dimPtr );
                    memcpy( x, cartella, lPercorso );
                    memcpy( (void*)((size_t)x+lPercorso), fd.cFileName, lNomeFile+1 );
                    y = (void*)(((size_t)y)+dimPtr);
                    x = (void*)((size_t)x+lPercorso+lNomeFile+1);
                    ++i;
                }
            }
        }
        else {
            free( dTmp );
            dTmp = NULL;
        }

        FindClose( hnd );
        return (char**)dTmp;
    }

    return NULL;
}
Ultima modifica effettuata da AldoBaldo 08/10/20 20:56
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
19/10/20 13:33
musical wrighter
Aldo Baldo wow complimenti per il lavorone che hai fatto! Solo che non ho capito nulla. Ho compreso che mi ci vorrà ancora un po di studio e di pratica prima di realizzare a mia volta una rova simile. E non riesco a seguirti nella logica anche perché il tuo sorgente apparte l'utilizzo di una propria classe per il resto somiglia molto più a c che a c++. Devo aprire un'altra discussione o posso fare quì la domanda sui metodi FindFirstFile(), FindNextFile() e FindClose() si possono usare anche in c++ o soltanto in c, e c'è un modo per usarli per copiare i nomi dei file contenuti nella directory in cui si troval'exe in delle stringhe. Sarebbe meglio proprio string e non array di char. Grazie in anticipo e buona giornata
aaa