PDA

View Full Version : Perchè C++ sotto Windows diventa così complicato!


ChriD
24-07-2009, 16:35
Volevo scrivere una semplice applicazione sotto windows in c++ per pare alcune modifiche ai dei files radicati in una specifica directory!
Ho scaricato Visual C++ Express! L'applicazione lavora tramite console per il momento, poi in futuro vedrò di realizzare qualcosa di grafico!

In Java l'avrei fatto in poco tempo ma sotto windows "MAMMA MIA"!!!

Già solo ottenere la lista dei files in una directory diventa un casino....

Ho trovato un pò di codice in rete

WIN32_FIND_DATA mydata;
HANDLE myHandle=FindFirstFile("c:\\prova",&mydata);


Questo servirebbe per leggere il primo file e piazzarlo in mydata! Il problema è che già quel "c:\\prova" non lo vuole perchè dice che non riesce a fare una conversione da const char* a LPCWSTR (ma che roba è :mbe:)

Premetto che di C++ non me ne intendo molto ma ho masticato parecchio C sotto linux (sono laureato in informatica) e solo un pochino di c++!

Successivamente per leggere tutti i files potrei fare un ciclo invocando il metodo FindNextFile e controllare fin quando non ritorno al file di partenza!

Il discorso è che mi mancano le conoscenze sulle API Win32 e l'ambiente .net! Tuttavi per il programmino (mi vergono anche a chiamarlo così) che voglio realizzare non credevo ci volesse tutta questa conoscenza... boh :boh:

Mi date una mano :D

banryu79
24-07-2009, 16:52
Il discorso è che mi mancano le conoscenze sulle API Win32 e l'ambiente .net! Tuttavi per il programmino (mi vergono anche a chiamarlo così) che voglio realizzare non credevo ci volesse tutta questa conoscenza... boh :boh:


Il problema è questo.
Interfacciarsi con le API Win32 per scrivere un'applicazione (magari con tanto di GUI) è sicuramente più complesso che realizzare l'equivalente in Java o in .NET.

Soprattutto quando in Java hai già lavorato e invece in C++ su Windows sei alle prime armi. Direi che è normale "sentire un certo sbalzo", in questi casi.
Percui sì: ci vuole "tutta quella conoscenza".

Se vuoi ricevere aiuti specifici dovresti postare domande specifiche e/o spezzoni di codice sul quale hai dubbi; se qualche utente esperto in materia ti legge avrai la possibilità di ricevere un aiuto specifico.

PGI-Bis
24-07-2009, 17:15
Qui trovi una soluzione ufficiale:

http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx

WarDuck
24-07-2009, 17:16
Personalmente ti consiglio di usare C# :D

cdimauro
24-07-2009, 17:34
Io gli consiglio di usare un linguaggio "agile". In 3 righe di codice:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for File in os.listdir(r'C:\\'):
... print File
...
Boot
bootmgr
BOOTSECT.BAK
Documents and Settings
grldr
Ice-3.2.0
IcePy-3.2.0
MSOCache
pagefile.sys
PerfLogs
Program Files
Program Files (x86)
ProgramData
Programmi
ProjectTemplates
Python25
PythonForDelphi
System Volume Information
Temp
tmp
Users
Windows
:cool:

shinya
24-07-2009, 18:01
Io gli consiglio di usare un linguaggio "agile". In 3 righe di codice:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for File in os.listdir(r'C:\\'):
... print File
...

In 2 righe :Prrr:

USING: io io.directories ;
"c:\\" directory-files [ print ] each

:cool: :cool:

shinya
24-07-2009, 18:07
Il discorso è che mi mancano le conoscenze sulle API Win32 e l'ambiente .net! Tuttavi per il programmino (mi vergono anche a chiamarlo così) che voglio realizzare non credevo ci volesse tutta questa conoscenza... boh :boh:

Mi date una mano :D
Sei obbligato ad usare le API Win32? Perchè altrimenti potresti considerare una libreria più sana di mente, tipo...
http://www.boost.org/doc/libs/1_39_0/libs/filesystem/doc/index.htm

PGI-Bis
24-07-2009, 18:11
1 riga:

(FileDirectory on: 'z:\\') fileNames do: [:x|Transcript show: x;cr.].

javaboy
24-07-2009, 18:18
Anche in c++ puoi fare queste cose comodamente.
Basta usare Qt o boost o qualche altra libreria...

^TiGeRShArK^
24-07-2009, 18:30
anch'io in una riga:

Directory.GetFiles(@"c:\temp").ToList().ForEach(Console.WriteLine);

:p

banryu79
24-07-2009, 18:51
manca solo la versione in batch... :asd:

E comunque dubito che possa usare Python, Factor, Squeak o C#...

^TiGeRShArK^
24-07-2009, 18:52
manca solo la versione in batch... :asd:

quella è la + semplice e corta. :O

dir c:\temp


:asd:

PGI-Bis
24-07-2009, 18:55
su Unix se non sbaglio è anche più corta:

ls laCartella

:D

ChriD
24-07-2009, 19:02
Qui trovi una soluzione ufficiale:

http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx

Alla faccia e del bicarbonato di sodio :eekk:

Personalmente ti consiglio di usare C# :D

Mi piacerebbe impararlo ma ho paura di confondermi ancora più le idee.... Già la programmazione a oggetti del c++ la devo ancora digerire bene....

Io gli consiglio di usare un linguaggio "agile". In 3 righe di codice:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for File in os.listdir(r'C:\\'):
... print File
...
Boot
bootmgr
BOOTSECT.BAK
Documents and Settings
grldr
Ice-3.2.0
IcePy-3.2.0
MSOCache
pagefile.sys
PerfLogs
Program Files
Program Files (x86)
ProgramData
Programmi
ProjectTemplates
Python25
PythonForDelphi
System Volume Information
Temp
tmp
Users
Windows
:cool:

Mammamia.... codice python all'università non ne abbiamo mai visto.... effettivamente non pensavo fosse così ridotto al minimo! Quasi quasi....

Sei obbligato ad usare le API Win32? Perchè altrimenti potresti considerare una libreria più sana di mente, tipo...
http://www.boost.org/doc/libs/1_39_0/libs/filesystem/doc/index.htm

No non sono obbligato... sto dando un'occhiata alla liberia che mi hai linkato, grazie ;)

Anche in c++ puoi fare queste cose comodamente.
Basta usare Qt o boost o qualche altra libreria...

Ammetto la mia completa ignoranza su queste librerie (ma ne ho sentito parlare)! Anche a queste darò un'occhiata ;)

Grazie a tutti..... appena ho tempo mi rimetto a lavoro e nel caso avessi nuovamente bisogno mi rifarò vivo :D
Mi fa piacere che sia nata questa "sfida" nel rendere il codice quanto più ridotto possibile :D

banryu79
24-07-2009, 19:09
A proposito di:

Mi piacerebbe impararlo ma ho paura di confondermi ancora più le idee.... Già la programmazione a oggetti del c++ la devo ancora digerire bene....

...

Mammamia.... codice python all'università non ne abbiamo mai visto.... effettivamente non pensavo fosse così ridotto al minimo! Quasi quasi....

Se puoi scegliere un linguaggio di programmazione per facilitarti la vita in generale potrebbe essere meglio sceglierlo di alto livello.

Se pensi che imparare C# sia più difficile che C++, bhe, forse è il caso che leggi questo articolo (http://www.appuntidigitali.it/2506/quale-linguaggio-per-imparare-a-programmare/).

Fidati che è più facile imparare la programmazione OO con C# (o Python o Java o SmallTalk) che non con C++.

^TiGeRShArK^
24-07-2009, 19:54
Mammamia.... codice python all'università non ne abbiamo mai visto.... effettivamente non pensavo fosse così ridotto al minimo! Quasi quasi....

...ma guarda che questo è C#:

Directory.GetFiles(@"c:\temp").ToList().ForEach(Console.WriteLine);

e mi pare assolutamente confrontabile come lunghezza al python... :stordita:

||ElChE||88
24-07-2009, 20:36
Mi fa piacere che sia nata questa "sfida" nel rendere il codice quanto più ridotto possibile :D
Sarebbe meglio rendere il codice più leggibile, non più ridotto.

^TiGeRShArK^
24-07-2009, 20:39
Sarebbe meglio rendere il codice più leggibile, non più ridotto.

Il mio è chiarissimo, mi faccio dare la lista dei file dall'oggetto directory, la converto in lista (questa è l'unica cosa che non mi piace perchè l'iterable non supporta direttamente il foreach) e su ogni file lancio la stampa. :p
Mi pare ufficientemente chiaro a parte il ToList che mi sta sulle balle (e che si può comunque evitare con una Extension).. :mad:

||ElChE||88
24-07-2009, 20:56
Il mio è chiarissimo
Su questo non posso esprimermi, essendo il C# il mio linguaggio "principale" sarei imparziale.
mi faccio dare la lista dei file dall'oggetto directory, la converto in lista (questa è l'unica cosa che non mi piace perchè l'iterable non supporta direttamente il foreach)
Più che altro è un po' uno spreco convertire l'array in lista, in questo caso un foreach normale ci sarebbe anche stato bene.
Ripeto, meglio leggibile che corto. :O
Mi pare ufficientemente chiaro a parte il ToList che mi sta sulle balle (e che si può comunque evitare con una Extension).. :mad:
Lo penso anch'io, ancora meglio se fatta per supportare la concatenazione (basta un semplice return :D ).

cdimauro
24-07-2009, 21:19
import os
print os.listdir(r'C:\\')
Ditemi se non è leggibilissimo questo. :O

Per gli amanti della singola riga di codice:
import os; print os.listdir(r'C:\\')
:cool:
Mammamia.... codice python all'università non ne abbiamo mai visto.... effettivamente non pensavo fosse così ridotto al minimo! Quasi quasi....
[...]
Grazie a tutti..... appena ho tempo mi rimetto a lavoro e nel caso avessi nuovamente bisogno mi rifarò vivo :D
Mi fa piacere che sia nata questa "sfida" nel rendere il codice quanto più ridotto possibile :D
L'importante è risolvere il problema, non buttare sangue su un listatone quando con un altro linguaggio puoi fare la stessa in molto meno tempo.

Produttività in primis. ;)

PGI-Bis
24-07-2009, 21:28
Per gli amanti della singola riga di codice:
import os; print os.listdir(r'C:\\')

Non vale, sono due enunciati :Prrr:

marko.fatto
24-07-2009, 21:59
puts Dir.entries("C:\\")
:stordita: :fagiano:

cdimauro
24-07-2009, 22:38
Non vale, sono due enunciati :Prrr:
exec "import os; print os.listdir(r'C:\')"
Fixed. :O

Don't underestimate the power of Python. :cool:

PGI-Bis
25-07-2009, 12:19
Quello è un enunciato. Orrendo, ma uno.

AnonimoVeneziano
25-07-2009, 12:37
Volevo scrivere una semplice applicazione sotto windows in c++ per pare alcune modifiche ai dei files radicati in una specifica directory!
Ho scaricato Visual C++ Express! L'applicazione lavora tramite console per il momento, poi in futuro vedrò di realizzare qualcosa di grafico!

In Java l'avrei fatto in poco tempo ma sotto windows "MAMMA MIA"!!!

Già solo ottenere la lista dei files in una directory diventa un casino....

Ho trovato un pò di codice in rete

WIN32_FIND_DATA mydata;
HANDLE myHandle=FindFirstFile("c:\\prova",&mydata);


Questo servirebbe per leggere il primo file e piazzarlo in mydata! Il problema è che già quel "c:\\prova" non lo vuole perchè dice che non riesce a fare una conversione da const char* a LPCWSTR (ma che roba è :mbe:)

Premetto che di C++ non me ne intendo molto ma ho masticato parecchio C sotto linux (sono laureato in informatica) e solo un pochino di c++!

Successivamente per leggere tutti i files potrei fare un ciclo invocando il metodo FindNextFile e controllare fin quando non ritorno al file di partenza!

Il discorso è che mi mancano le conoscenze sulle API Win32 e l'ambiente .net! Tuttavi per il programmino (mi vergono anche a chiamarlo così) che voglio realizzare non credevo ci volesse tutta questa conoscenza... boh :boh:

Mi date una mano :D

Il problema è che stai cercando di mandare in pasto a una funzione che accetta solo stringhe tipo Unicode (LPCWSTR) delle stringhe di tipo multi-byte (ossia le classiche const char[]) .

Le soluzioni sono due:

1) Inserisci ogni stringa che dai in pasto alle API di Windows in una macro _T() che si occupa lei di convertire la stringa nel tipo più opportuno .

Esempio:


WIN32_FIND_DATA mydata;
HANDLE myHandle=FindFirstFile(_T("c:\\prova"),&mydata);


2) Vai nelle proprietà del progetto (dal menu Project->Properties) e modifichi in Configuration Properties->General il parametro "Character Set" da Unicode a Multi-byte. Così puoi usare le stringhe classiche C senza anteporre nessuna MACRO.

Ciao

cdimauro
25-07-2009, 12:57
Quello è un enunciato. Orrendo, ma uno.
Eh, lo so: fa talmente schifo pure a me, che non lo adopero mai. :asd:

Ma non avevo scelta, per arrivare a usarne uno soltanto. :sob:

Vincenzo1968
25-07-2009, 17:28
Tempo fa avevo sviluppato una dll. Puoi scaricarla qui (http://www.guidealgoritmi.it/public/ScanDirDll.zip).

La dll esporta una funzione: DirWalk. Gli argomenti da passare sono:

- La stringa contenente la cartella che si vuole analizzare.
- Un valore booleano che indica se si vogliono reperire anche i file nelle sottocartelle; FALSE indica che vogliamo ottenere i file nella sola cartella corrente. TRUE indica che vogliamo anche quelli nelle sottocartelle.
- Un puntatore a una funzione di tipo void e che accetta un parametro di tipo LPDIRWALKDATA; quest'ultimo è una struttura contenente i dati del file(percorso e nome). La funzione va definita nel client e viene richiamata dalla dll ogni volta che trova un nuovo file.

Nell'esempio seguente stampiamo tutti i file nella cartella "c:\Book" (e nelle sue sottocartelle):


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "scandirdll.h"

// #pragma comment(lib, "ScanDirDll.lib")

void CALLBACK OnChange(LPDIRWALKDATA pDW)
{
if ( pDW->fIsDir )
printf("\nFiles nella cartella '%s' :\n", pDW->szCurrPath);
else
printf("%s\n", pDW->FindData.cFileName);
}

int main(int argc, char* argv[])
{
DirWalk(__TEXT("c:\\Book"), TRUE, OnChange);

return 0;
}


P.S.: ovviamente la dll va fornita insieme all'eseguibile(nella sua stessa cartella o nella cartella di sistema di windows). Per compilare il client, è necessario indicare al linker il file di import "ScanDirDll.lib".

EDIT: per linkare il file "ScanDirDll.lib" puoi usare anche la seguente direttiva del preprocessore:


#pragma comment(lib, "ScanDirDll.lib")

-Slash
25-07-2009, 19:29
In 2 righe :Prrr:

USING: io io.directories ;
"c:\\" directory-files [ print ] each

:cool: :cool:
Saranno anche due righe, ma la sintassi secondo me è oscena :stordita:

marko.fatto
25-07-2009, 20:00
Ma non avevo scelta, per arrivare a usarne uno soltanto. :sob:

bastava scegliere ruby :Prrr:

shinya
25-07-2009, 22:19
Saranno anche due righe, ma la sintassi secondo me è oscena :stordita:
Tipica reazione:"Fa schifo perchè non lo capisco". E' evidente che non conosci ciò di cui stai parlando.

zulutown
26-07-2009, 11:57
L'importante è risolvere il problema, non buttare sangue su un listatone quando con un altro linguaggio puoi fare la stessa in molto meno tempo.

Produttività in primis. ;)

La produttività è quando si deve metter mano a codice scritto da altri senza avere la tentazione di lanciare il pc contro il muro.

cdimauro
26-07-2009, 19:22
bastava scegliere ruby :Prrr:
Ci sono riuscito anche senza. :cool:

Ma Dir è un oggetto built-in di Ruby?
La produttività è quando si deve metter mano a codice scritto da altri senza avere la tentazione di lanciare il pc contro il muro.
Ecco perché in genere preferisco riscriverlo da capo piuttosto che cercare di capire quello che hanno fatto gli altri. :p

banryu79
27-07-2009, 09:29
La produttività è quando si deve metter mano a codice scritto da altri senza avere la tentazione di lanciare il pc contro il muro.
Parole sante.
Infatti in questi casi preferisco avere a che fare con del codice "che parla", non con del codice "che stringe le chiappe" :ciapet:

banryu79
27-07-2009, 09:31
Ecco perché in genere preferisco riscriverlo da capo piuttosto che cercare di capire quello che hanno fatto gli altri. :p
Bhe a me è capitato di dover integrare del codice altrui, scritto a muzzo: alla fine ho dovuto riscrivere varie classi.
Il refactoring mi è stato di grande aiuto per riscrivere quel codice, ma il fatto è che comunque devi arrivare a capire cosa fa, in modo o nell'altro.

marko.fatto
27-07-2009, 11:18
Ci sono riuscito anche senza. :cool:

Ma Dir è un oggetto built-in di Ruby?

Ci sei mezzo riuscito così, quella "cosa" vale la metà :Prrr:

Questo è Dir (http://ruby-doc.org/core/classes/Dir.html)

cdimauro
27-07-2009, 11:26
Non ho ancora capito se si può utilizzare immediatamente Dir senza prima necessariamente includerlo/importarlo. :stordita:

marko.fatto
27-07-2009, 11:59
si si può, quella "riga" di codice è valida
irb(main):001:0> puts Dir.entries("C:\\")
$Recycle.Bin
ATI
autoexec.bat
config.sys
Documents and Settings
hiberfil.sys
MSOCache
pagefile.sys
PerfLogs
Program Files
ProgramData
Recovery
Ruby
System Volume Information
Users
Windows
=> nil