Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - comando di sistema Windows in un codice c++ mi sapreste dire dove sto sbagliando e come deve essere eventualmente cambiato?
Forum - C/C++ - comando di sistema Windows in un codice c++ mi sapreste dire dove sto sbagliando e come deve essere eventualmente cambiato? - Pagina 2

Pagine: [ 1 2 3 ] Precedente | Prossimo
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 22:11
Sabato, 12/09/2020
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 nessuno il 12/09/2020 alle 22:27


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:26
Sabato, 12/09/2020
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.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:16
Domenica, 13/09/2020
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.


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:45
Domenica, 13/09/2020
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.
PM Quote
Avatar
musical wrighter (Normal User)
Newbie


Messaggi: 17
Iscritto: 26/09/2018

Segnala al moderatore
Postato alle 16:52
Giovedì, 08/10/2020
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
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <Windows.h>
  5. #include <sapi.h>
  6. using namespace std;
  7. #pragma comment(lib,"winmm.lib")
  8. int main()
  9. {
  10.         system("dir /b *.wav >\"appunti\"");
  11.         ifstream appunti("appunti");
  12.         ISpVoice* pVoice = NULL;
  13.         if (FAILED(::CoInitialize(NULL)))
  14.                 return FALSE;
  15.         HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)& pVoice);
  16.         if (SUCCEEDED(hr))
  17.         {
  18.                 while (!appunti.eof())
  19.                 {
  20.                         string brano;
  21.                         getline(appunti, brano);
  22.                         int cut = brano.size() - 4;
  23.                         string nome = brano.substr(0, cut);
  24.                         wstring cs(brano.begin(), brano.end()), cv(nome.begin(), nome.end());
  25. cout << nome; hr = pVoice->Speak(cv.c_str(), 0, NULL);
  26.                         PlaySound(cs.c_str(), NULL, SND_FILENAME);
  27. }
  28.                 cout << "arrivederci"; hr = pVoice->Speak(L"arrivederci", 0, NULL);
  29.         }
  30.         pVoice->Release();
  31.         pVoice = NULL;
  32.         ::CoUninitialize();
  33. appunti.close();
  34. }


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 il 08/10/2020 alle 20:44
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:49
Giovedì, 08/10/2020
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

Codice sorgente - presumibilmente C++

  1. #include <cstdio>
  2. #include "elencofile.h"
  3.  
  4. int main() {
  5.     try {
  6.         ElencoFile ef; // elenca i file presenti nella working directory
  7.  
  8.         for( unsigned int i=0; i<ef.TotaleFile(); ++i )
  9.             printf( "%s\n", ef.NomeFile(i) );
  10.  
  11.         return 0;
  12.     } catch( ... ) {
  13.         puts( "Errore!" );
  14.         return 1;
  15.     }
  16. }



file elenco_file.h

Codice sorgente - presumibilmente C++

  1. #ifndef ELENCOFILE_H
  2. #define ELENCOFILE_H
  3.  
  4. #include <windows.h>
  5. #include <cstdlib>
  6. #include <cstring>
  7.  
  8. class ElencoFile {
  9.     public:
  10.         ElencoFile( const char *cartella = NULL );
  11.         virtual ~ElencoFile();
  12.         ElencoFile(const ElencoFile& other);
  13.         ElencoFile& operator=(const ElencoFile& other);
  14.  
  15.         bool AcquisisciElencoDaCartella( const char *cartella );
  16.         unsigned int TotaleFile( void ) const { return tf; }
  17.         const char *NomeFile( unsigned int indice ) const;
  18.  
  19.     protected:
  20.  
  21.     private:
  22.         char **ef;       // ef: elenco file
  23.         unsigned int tf; // tf: totale file
  24.         size_t dd;       // dd: dimensioni dati
  25.  
  26.         char *DuplicaPercorso( const char *percorso );
  27.         bool AnalizzaContenutoCartella(
  28.             const char *cartella, unsigned int *qFile, size_t *dDati );
  29.         char **CreaElencoDaCartella(
  30.             const char *cartella, unsigned int qFile, size_t dDati );
  31. };
  32.  
  33. #endif // ELENCOFILE_H



file elenco_file.cpp

Codice sorgente - presumibilmente C++

  1. #include "elencofile.h"
  2.  
  3. ElencoFile::ElencoFile( const char *cartella ) {
  4.     ef = NULL;
  5.     tf = 0;
  6.     dd = 0;
  7.  
  8.     if( !AcquisisciElencoDaCartella(cartella) ) throw false;
  9. }
  10.  
  11. ElencoFile::~ElencoFile() {
  12.     if( ef ) delete[] ef;
  13. }
  14.  
  15. ElencoFile::ElencoFile(const ElencoFile& other) {
  16.     ef = NULL;
  17.     tf = 0;
  18.     dd = 0;
  19.     *this = other;
  20. }
  21.  
  22. ElencoFile& ElencoFile::operator=(const ElencoFile& rhs) {
  23.     if (this == &rhs) return *this; // handle self assignment
  24.  
  25.     if( rhs.ef ) {
  26.         void *tmp = malloc( rhs.dd );
  27.         if( NULL == tmp ) throw false;
  28.         memcpy( tmp, rhs.ef, rhs.dd );
  29.         if( ef ) free( ef );
  30.         ef = (char**)tmp;
  31.         tf = rhs.tf;
  32.         dd = rhs.dd;
  33.     }
  34.  
  35.     return *this;
  36. }
  37.  
  38. bool ElencoFile::AcquisisciElencoDaCartella( const char *cartella ) {
  39.     char *dupPercCart = NULL;
  40.     bool ok = false;
  41.  
  42.     if( (dupPercCart=DuplicaPercorso(cartella)) ) {
  43.         unsigned int tfTmp = 0;
  44.         size_t ddTmp       = 0;
  45.  
  46.         if( AnalizzaContenutoCartella(dupPercCart,&tfTmp,&ddTmp) ) {
  47.             char **efTmp = CreaElencoDaCartella( dupPercCart, tfTmp, ddTmp );
  48.  
  49.             if( NULL != efTmp ) {
  50.                 if( ef ) free( ef );
  51.                 ef = efTmp;
  52.                 tf = tfTmp;
  53.                 dd = ddTmp;
  54.                 ok = true;
  55.             }
  56.         }
  57.  
  58.         free( (void*)dupPercCart );
  59.     }
  60.  
  61.     return ok;
  62. }
  63.  
  64. const char *ElencoFile::NomeFile( unsigned int indice ) const {
  65.     if( ef && indice<tf )
  66.         return ef[indice];
  67.     else return NULL;
  68. }
  69.  
  70. // privata
  71. char *ElencoFile::DuplicaPercorso( const char *percorso ) {
  72.     char *buff = NULL;
  73.  
  74.     if( NULL==percorso ) {
  75.         DWORD dimBuff = GetCurrentDirectory( 0, NULL );
  76.         if( (buff=(char*)calloc(dimBuff+4,sizeof(*buff))) ) {
  77.             GetCurrentDirectory( dimBuff, buff );
  78.             memcpy( buff+dimBuff-1, "\\*.*", 5 );
  79.         }
  80.     }
  81.     else {
  82.         size_t l = lstrlen( percorso );
  83.         if( (buff=(char*)malloc(l+5)) ) {
  84.             memcpy( buff, percorso, l );
  85.             memcpy( buff+l, "\\*.*", 5 );
  86.         }
  87.     }
  88.  
  89.     return buff;
  90. }
  91.  
  92. // privata
  93. bool ElencoFile::AnalizzaContenutoCartella(
  94.     const char *cartella, unsigned int *qFile, size_t *dDati ) {
  95.     if( !cartella || !qFile || !dDati ) return false;
  96.  
  97.     size_t lNomeCartella = lstrlen(cartella)-3;
  98.     WIN32_FIND_DATA fd = {0};
  99.     HANDLE hnd = NULL;
  100.  
  101.     *qFile = 0;
  102.     *dDati = 0;
  103.  
  104.     hnd = FindFirstFile( cartella, &fd );
  105.  
  106.     if( INVALID_HANDLE_VALUE != hnd ) {
  107.         if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
  108.             while( FindNextFile(hnd,&fd) ) {
  109.                 if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
  110.                     *dDati += sizeof(char*)+lNomeCartella+lstrlen(fd.cFileName)+1;
  111.                     ++(*qFile);
  112.                 }
  113.             }
  114.         }
  115.  
  116.         FindClose( hnd );
  117.         return true;
  118.     }
  119.  
  120.     return false;
  121. }
  122.  
  123. // privata
  124. char **ElencoFile::CreaElencoDaCartella(
  125.     const char *cartella, unsigned int qFile, size_t dDati ) {
  126.     if( !cartella ) return NULL;
  127.  
  128.     void *dTmp = calloc( dDati, 1 );
  129.     if( !dTmp ) return NULL;
  130.    
  131.     // Lo scopo della gran confusione creata con una pletora di puntatori e cast
  132.     // nelle prossime righe, e' inserire tutti i percorsi+nomi dei file in un
  133.     // unico blocco di memoria al quale sia possibile accedere come ad un comune
  134.     // array di stringhe C. Inutilmente complicato? Puo' darsi. Pasticciato?
  135.     // Puo' darsi. Pero' sembra funzionarea a dovere. :)
  136.    
  137.     size_t lPercorso = lstrlen(cartella)-3;
  138.     size_t dimPtr = sizeof(char*);
  139.     void *y = dTmp;
  140.     void *x = ((void*)(((size_t)dTmp)+qFile*dimPtr));
  141.     unsigned int i=0;
  142.  
  143.     WIN32_FIND_DATA fd = {0};
  144.     HANDLE hnd = FindFirstFile( cartella, &fd );
  145.  
  146.     if( INVALID_HANDLE_VALUE != hnd ) {
  147.         if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
  148.             while( FindNextFile(hnd,&fd) && i<qFile ) {
  149.                 if( !(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ) {
  150.                     size_t lNomeFile = lstrlen(fd.cFileName);
  151.                     memcpy( y, &x, dimPtr );
  152.                     memcpy( x, cartella, lPercorso );
  153.                     memcpy( (void*)((size_t)x+lPercorso), fd.cFileName, lNomeFile+1 );
  154.                     y = (void*)(((size_t)y)+dimPtr);
  155.                     x = (void*)((size_t)x+lPercorso+lNomeFile+1);
  156.                     ++i;
  157.                 }
  158.             }
  159.         }
  160.         else {
  161.             free( dTmp );
  162.             dTmp = NULL;
  163.         }
  164.  
  165.         FindClose( hnd );
  166.         return (char**)dTmp;
  167.     }
  168.  
  169.     return NULL;
  170. }


Ultima modifica effettuata da AldoBaldo il 08/10/2020 alle 22: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.
PM Quote
Avatar
musical wrighter (Normal User)
Newbie


Messaggi: 17
Iscritto: 26/09/2018

Segnala al moderatore
Postato alle 15:33
Lunedì, 19/10/2020
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

PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 20:47
Lunedì, 19/10/2020
In effetti devo ammettere che anche quando uso ALCUNE della caratteristiche del C++ lo faccio alla maniera di uno che ha in mente il C, per cui hai visto giusto. E' per sentirmi su un terreno più famigliare che (ad esempio) anche all'interno delle classi del C++ uso spesso malloc/calloc/realloc invece di new. Per la stessa ragione evito di usare string e prediligo gli array di char. Avrai anche notato che preferisco non ricorrere al mettanismo throw/catch se non in casi in cui è impossibile fare diversamente. Tollerabile, ma non credo siano buone pratiche.

Per chi è pratico del C++, usare oggetti di tipo string non dovrebbe essere un problema, anche perché se non erro così facendo eviti tutte le problematiche legate alla necessità di conoscere in anticipo le dimensioni della stringa risultante (avrai notato che ho dovuto fare due "scannate" della cartella, la prima delle quale ha la sola funzione di conoscere le dimensioni della memoria da allocare per "ospitare" l'array di stringhe C).

Le tre funzioni di ricerca dei file possono essere usate sia in C, sia in C++. Cambia solo il modo in cui "estrai" dalla struttura WIN32_FIND_DATA i dati che ti interessano (essenzialmente il campo cFileName).

Per avere informazioni sulle funzioni di ricerca che ho usato la fonte di informazioni più appropriata è msdn:

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/
https://docs.microsoft.com/en-us/windows/win32/fileio/listi ...

Effettivamente è tutto un po' complesso (per il mio livello).


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.
PM Quote
Pagine: [ 1 2 3 ] Precedente | Prossimo