PDA

Visualizza la versione completa : [c++] Funzione system("copy ")


Falcon_God
10-11-2009, 00:36
Salve, sono nuovo di questo forum. Mi sto cimentando da poco tempo nel modo della programmazione c++. Ma saltiamo i convenevoli e passiamo al punto della situazione...

Sto scrivendo un programma nel quale mi serve che l'utente mi inserisca il percorso di un file, il programma mi prende la stringa me la riformatta in modo da essere presa correttamente dalla funzione system("copy "). Ma mi da sempre lo stesso errore, ossia mi dice "impossibile trovare il file specificato". Naturalmente non vi sto a precisare che il file c'è, l'indirizzo è giusto e la cartella di destinazione esite.

PS. Utilizzo codeblocks come ambiente di programmazione su win7

Vi metto qui il codice che ho scritto:



#include <iostream>
#include <windows.h>
#include <string>

using namespace std;

string risistema_stringa(string a);

int main()
{
string a;
getline(cin,a);

string b = risistema_stringa(a);

system("copy b c:\\ciao\\ciao.txt");

return 0;
}

string risistema_stringa(string a)
{
if(a.length()==0)
return "";

else
{
if(a.substr(0,1)==" ")
return "\" \""+risistema_stringa(a.substr(1,1-a.length()));

else if(a.substr(0,1)=="\\")
return "\\"+risistema_stringa(a.substr(1,1-a.length()));

else
return a.substr(0,1)+risistema_stringa(a.substr(1,1-a.length()));
}
}


Se riuscite a darmi una mano, ve ne sarei molto grato.

Grazie dell'attenzione ;)

shodan
10-11-2009, 00:58
Quel che viene eseguito è quello inviato alla system().
b esiste? (Perché non stai concatenando la stringa. Non si fa in quel modo)
L'alternativa alla system è :
CopyFile: http://msdn.microsoft.com/en-us/library/aa363851%28VS.85%29.aspx


...
BOOL bFailIfExists = FALSE;
CopyFile(b.c_str(), "c:\\ciao\\ciao.txt", bFailIfExists);
...

Falcon_God
10-11-2009, 01:17
Originariamente inviato da shodan
Quel che viene eseguito è quello inviato alla system().
b esiste? (Perché non stai concatenando la stringa. Non si fa in quel modo)
L'alternativa alla system è :
CopyFile: http://msdn.microsoft.com/en-us/library/aa363851%28VS.85%29.aspx


...
BOOL bFailIfExists = FALSE;
CopyFile(b.c_str(), "c:\\ciao\\ciao.txt", bFailIfExists);
...


grazie della risposta.

b esiste, se fai una prova di otuput o segui un debug, vedi che la stringa viene riformattata correttamente e la funzione di ricorsione funziona a dovere...alemeno su questo penso di essere sicuro.

Non ho capito il fatto della concatenazione, scusa, ma non sono molto ferrato, da quel poco che ho studiato mi sembra che in c++ la concatenazione di stringhe si faccia semplicemente con l'operatore di somma, in quanto è stato fatto un overloading della funzione nella libreria string che ho caricato con l'include. Se ho detto qualche cavolata correggetemi.

Adesso provo quella funzione che mi hai passato, anche perchè non mi piace proprio quella system(copy), secondo me il problema sta li.

PS.Qualche info sul quel boleano bFailIfExists??

PPS.Perchè hai dichiarato bFailIfExists con BOOL in maiuscolo? Sapevo che i bool si dichiaravano in minuscolo, cambia qualcosa? o e solo formalità?

Grazie ancora delle risposte e scusatemi l'ignoranza :P

PPPS. Quella funzione che mi hai passato se non sbaglio utilizza le api di windows, vero? Quindi devo aggiungere negli include conio.h, vero?

Falcon_God
10-11-2009, 01:33
Grazie mille, la funzione che mi hai dato te funziona alla grande, il resto del programma è rimasto uguale...c'era qualche problema nella system()...bho.

Vabbè, l'importante è che funzioni :P

PS. mi sono già risposto da solo ad alcune domande, del tipo la libreria conio.h non la devo inserire e bool o BOOL è la stessa cosa. Ma sul significato di quel parametro booleano...bho

shodan
10-11-2009, 01:42
Originariamente inviato da Falcon_God
b esiste, se fai una prova di otuput o segui un debug, vedi che la stringa viene riformattata correttamente e la funzione di ricorsione funziona a dovere...alemeno su questo penso di essere sicuro.

Non hai afferrato. La system invoca il prompt e gli passa letteralmente: copy b c:\ciao\\ciao.txt.
b viene interpretato come nome di file, non come qualcosa che elabori tu.



Non ho capito il fatto della concatenazione, scusa, ma non sono molto ferrato, da quel poco che ho studiato mi sembra che in c++ la concatenazione di stringhe si faccia semplicemente con l'operatore di somma, in quanto è stato fatto un overloading della funzione nella libreria string che ho caricato con l'include. Se ho detto qualche cavolata correggetemi.

Tutto giusto, ma tu hai scritto system("copy b c:\\ciao\\ciao.txt"); con l'intenzione di concatenare la stringa b all'interno della system()
Quello che dovevi scrivere era:


string command = string("copy ") + b + string(" c:\\ciao\\ciao.txt");
system(command.c_str());




PS.Qualche info sul quel boleano bFailIfExists??

Beh, il nome è auto esplicativo. Comunque quel link dice tutto. In breve: se il file esiste già e il parametro è TRUE la funzione fallisce, se FALSE sovrascrive il file.


PPS.Perchè hai dichiarato bFailIfExists con BOOL in maiuscolo? Sapevo che i bool si dichiaravano in minuscolo, cambia qualcosa? o e solo formalità?

Sono mele e pere. BOOL è un tipo di dato (in genere un int) usato dalle API Windows come valore boolean. bool è C++.


PPPS. Quella funzione che mi hai passato se non sbaglio utilizza le api di windows, vero? Quindi devo aggiungere negli include conio.h, vero?
No, quell'header non serve. Per le API Windows è sufficente windows.h (che già hai incluso).

Falcon_God
10-11-2009, 15:46
Sulle mele e pere del BOOL hai ragione, sono caduto in errore perchè se tu dichiari bFailIfExists come un normale bool funziona tutto uguale...misteri della fede :P

Ok, adesso ho capito che l'errore era nella concatenazione delle stringhe, come dicevi tu. E come da te proposto ho risolto tutto con quella funzioncina c_str(). Sinceramente è la prima volta che la vedo, se mi puoi dire che fa in pratica...

Adesso ho risistemato il codice, ho dovuto modificare anche la ricorsione, visto che implementando il codice da te proposto nel mio, non serve più una riformattazione per gli spazi. Adesso funziona tutto. Però sono arrivato a un altro problema, ossia la verifica che il file in questione sia copiato a dovere. Io ho pensato di includere la classe fstrem, dichiarare un ifstream a e aprirlo con la funzione a.open(b.c_str()), dove b è l'indirizzo dove dovrebbe essere stato copiato il file. A quel punto dichiaro un bool ok e lo metto true se la funzione a.fail() non mi genera errore. Cosi uso il booleano ok per il feedback che mi serviva.

C'è un alternativa migliore per risolvere questo problema?

il codice che ho scritto cosi completato con questa ultima parte è questo.



#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>

using namespace std;

string risistema_stringa(string a);
bool controllo_copia(string b);

int main()
{
string a;
getline(cin, a);

string destinazione = "c:\\incolla\\prova.txt";

string origine = risistema_stringa(a);

origine = origine+"\\prova.txt";

BOOL bFailIfExists = false;
CopyFile(origine.c_str(), destinazione.c_str(), bFailIfExists);


bool ok = controllo_copia(destinazione.c_str());

cout<<endl<<ok<<endl;

return 0;
}

string risistema_stringa(string a)
{
if(a.length()==0)
return "";

else
{
if(a.substr(0,1)=="\\")
return "\\"+risistema_stringa(a.substr(1,1-a.length()));

else
return a.substr(0,1)+risistema_stringa(a.substr(1,1-a.length()));
}
}

bool controllo_copia(string b)
{
ifstream infile;

infile.open(b.c_str());

if (infile.fail())
{
return false;
}

return true;
}


Il tutto funziona, mi chiedevo solo se esiste un metodo migliore, se c'è qulache errore nel codice o se può andare. Grazie ;)

shodan
10-11-2009, 19:02
Originariamente inviato da Falcon_God
Sulle mele e pere del BOOL hai ragione, sono caduto in errore perchè se tu dichiari bFailIfExists come un normale bool funziona tutto uguale...misteri della fede :P

Nessun mistero. I true e false del C++ vengono tradotti come 1 e 0 durante l'assegnazione. Per capirsi: le API Windows hanno l'interfaccia C e in C non esiste uno specifico tipo di dato boolean.



se mi puoi dire che fa in pratica...

Serve a interfacciare le std::string alle C string.



C'è un alternativa migliore per risolvere questo problema?

Qualcosa del genere:


BOOL bFailIfExists = false;
BOOL success = CopyFile(origine.c_str(), destinazione.c_str(), bFailIfExists);
if (FAIL == success) {
DWORD err = GetLastError();
if (ERROR_FILE_NOT_FOUND == err) {
cout << "File: " << origine << " non esiste" << endl;
} else {
cout << "Copia fallita" << endl;
}
}




controllo_copia(destinazione.c_str());

Per funzionare funziona, solo che il prototipo prende già una std::string, quindi fai un passaggio in più. Corretto è:


controllo_copia(destinazione);

MItaly
11-11-2009, 00:28
Per inciso, volendo ti puoi scrivere in poche righe di codice la funzione FileCopy usando la sola libreria C++; in tale maniera ottieni codice portabile su ogni piattaforma.

Loading