 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Mie 10 Nov, 2010 10:24 pm Asunto: problemas con funcion recursiva |
|
|
Hola foro tengo la siguiente funcion recursiva, pero no me sale de ella a pesar de que se cumpla la condicion por la cual pregunto para salir
| Código: | void list (String Dir, TIdFTP * ftp, TMemo *m){
static String mainDir = Dir;
ftp->ChangeDir(Dir);
ftp->List("",true);
int count = ftp->DirectoryListing->Count;
if (count == 0) {
String dir = ftp->RetrieveCurrentDir();
ftp->ChangeDirUp();
ftp->RemoveDir(dir);
//main Dir = Dir = "/x
String a =ftp->RetrieveCurrentDir();
if (ftp->RetrieveCurrentDir() == mainDir) {
return ;
}
list (ftp->RetrieveCurrentDir(), ftp, m);
}else{
for (int i = 0; i <count>DirectoryListing->Items[i]->ItemType == ditDirectory) {
list (ftp->DirectoryListing->Items[i]->FileName, ftp, m);
}
if (ftp->DirectoryListing->Items[i]->ItemType == ditFile) {
ftp->Delete(ftp->DirectoryListing->Items[i]->FileName);
list (ftp->RetrieveCurrentDir(), ftp, m);
}
}
}
} |
Espero me puedan ayudar . Slaudos y gracias _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Vie 12 Nov, 2010 1:40 am Asunto: |
|
|
En un principio tiene buena pinta.
De todas formas, ¿puedes poner el codigo de nuevo con la opcion de Deshabilitar HTML, ya que el bucle for de abajo no se ve bien.
A simple vista se me ocurre si tienes en cuenta, si es un servidor FTP montado en WINDOWS, los directorios . y .. |
|
| Volver arriba |
|
 |
Touchsoftwares Master


Registrado: 16 Dic 2002Mensajes: 869Ubicación: MEXICO Playa del Carmen
|
Publicado: Vie 12 Nov, 2010 2:37 am Asunto: |
|
|
Revisa el segmento del la funcion donde se valida la salida
¿no se estara colando un condenado simbolo raro en la igualdad?
Por lo tanto nunca llega a ser igual
| Código: |
String a =ftp->RetrieveCurrentDir();
// ya probaste "ver" que es lo que sucede?
ShowMessage(ftp->RetrieveCurrentDir()+" "+mainDir);
if (ftp->RetrieveCurrentDir() == mainDir) {
return ;
|
_________________ Ing. Gabriel Góngora Navarrete
TouchSoftwares Inc
http://www.touchsoftwares.com |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Vie 12 Nov, 2010 12:35 pm Asunto: |
|
|
Muachas gracias por responder...
Aca dejo la funcion con HTML deshabilitado y antes habia un pequeño problema al cumplirse la condicion que ya esta arreglado y he comprobado en forma debug F8 que todo esta bien la condicion se cumple pero aunque se pase por el return no se sale de ella, sino que indistintamente se va para cualquier otro lado de la funcion hasta que se produce una excepcion...
| Código: | void RemoveFTPDir (String Dir, TIdFTP * ftp, TMemo *m){
static String mainDir = Dir;
ftp->ChangeDir(Dir);
ftp->List("",true);
int count = ftp->DirectoryListing->Count;
for (int i = 0; i < count; i++) {
//carpeta
if (ftp->DirectoryListing->Items[i]->ItemType == ditDirectory) {
RemoveFTPDir (ftp->DirectoryListing->Items[i]->FileName, ftp, m);
}
if (ftp->DirectoryListing->Items[i]->ItemType == ditFile) {
ftp->Delete(ftp->DirectoryListing->Items[i]->FileName);
RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m);
}
}
if (count == 0) {
String dir = ftp->RetrieveCurrentDir();
ftp->ChangeDirUp();
ftp->RemoveDir(dir);
if (dir == mainDir) return ;
RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m);
}
} |
_________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 12 Nov, 2010 1:34 pm Asunto: |
|
|
no es por saber, pero... ¿no sobra esta linea? | Código: | if (ftp->DirectoryListing->Items[i]->ItemType == ditFile) {
ftp->Delete(ftp->DirectoryListing->Items[i]->FileName);
RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m); <-------- ESTA
|
Veamos. Yo entiendo que entras en una carpeta del ftp. Si encuentra otra carpeta, llama de nuevo a la función remove. Si en esa carpeta ya no hay mas carpetas y solo archivos, borra el primero, i=0, y ¿vuelve a llamar a remove? creo que debería borrar todos los archivos y return.
Puedo estar equivocado, pero creo que eliminando esa linea no tendrás el problema
Saludos, Bosoft
PD: después de revisar mejor el código, creo:
Sobra lo del count==0
y después de la llamada al remove dentro del primer if, falta borrar la carpeta |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Vie 12 Nov, 2010 2:34 pm Asunto: |
|
|
Hola bosoft
| Cita: | | Veamos. Yo entiendo que entras en una carpeta del ftp. Si encuentra otra carpeta, llama de nuevo a la función remove. Si en esa carpeta ya no hay mas carpetas y solo archivos, borra el primero, i=0, y ¿vuelve a llamar a remove? creo que debería borrar todos los archivos y return. |
Imaginemos el siguiente caso:
carpeta1->fichero1
fichero2
carpeta2
Si entramos en carpeta1 y eliminamos fichero1 y luego hacemos un return como recomiendas veras que se quedan fichero2 y carpeta2 sin eliminar, por eso se vuelve a hacer una llamada ala función.
No entiendo porque me dices esto.
| Cita: | PD: después de revisar mejor el código, creo:
Sobra lo del count==0
y después de la llamada al remove dentro del primer if, falta borrar la carpeta |
_________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 12 Nov, 2010 3:05 pm Asunto: |
|
|
me parece que no me has entendido.
Dentro del for hay dos ifs. Según veo, ya que no he usado jamás esas funciones, el count controla cuantos elementos hay en la carpeta, ya sean directorios o archivos.
veamos tu ejemplo
carpeta1->fichero1
fichero2
carpeta2
entras en remove,
pilla el primer elemento, es directorio (carpeta1), llama a remove. Dentro del segundo remove, pilla primer elemento, es fichero (fichero1), lo borra y return (no hay mas elementos)
borra el dir (carpeta1)
pilla el segundo, es archivo (fichero2), lo borra
pilla el tercero, es carpeta (carpeta2), llama a remove ¿¿¿ ficheros??? return
borra el dir (carpeta2)
¿es eso lo que querías? el código quedaría mas o menos así. Recuerda que no se las sentencias necesarias.
| Código: | void RemoveFTPDir (String Dir, TIdFTP * ftp, TMemo *m){
static String mainDir = Dir;
ftp->ChangeDir(Dir);
ftp->List("",true);
int count = ftp->DirectoryListing->Count;
for (int i = 0; i <count>DirectoryListing->Items[i]->ItemType == ditDirectory) {
RemoveFTPDir (ftp->DirectoryListing->Items[i]->FileName, ftp, m);
// delete items[i]==dir;
}
if (ftp->DirectoryListing->Items[i]->ItemType == ditFile) {
ftp->Delete(ftp->DirectoryListing->Items[i]->FileName);
// delete items[i]==file;
}
} |
Saludos, Bosoft. |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Vie 12 Nov, 2010 3:23 pm Asunto: |
|
|
bosoft recuerda que cada vez que llamo a la funcion remove entra en el directorio que encontro lo que hace que la lista de elementos varie y que hallan x cnatidad de elementos
ejemplo
carpeta0
carpeta1->fichero1
fichero2
carpeta2
entre en carpeta1 y count vale 1 si eleimino el fichero debo luego salir a carpeta 0 luego listar count vale 3 entiendes siempre varia porque debo entrar en tantas carpetas hallan y luego salir y etc. Recuerda que solo se puede eliminar una carpeta si no tiene contenido dentro. _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 12 Nov, 2010 3:35 pm Asunto: |
|
|
Si, si, lo tengo todo en cuenta, menos el count. Es verdad, al eliminar un dir, el count descuenta y se lia parda para eso está asignado a un int que es el que usamos para el for.
Tengo una duda ¿el count contiene solo los elementos dentro de la carpeta? si tiene también los que están dentro de las subcarpetas, no he dicho nada y no se por donde pillarlo
En cambio si solo cuenta los de la carpeta actual el código que te he pasado debe funcionar
Como he visto que no ha salido bien, te lo vuelvo a poner con html desconectado
| Código: | void RemoveFTPDir (String Dir, TIdFTP * ftp, TMemo *m){
static String mainDir = Dir;
ftp->ChangeDir(Dir);
ftp->List("",true);
int count = ftp->DirectoryListing->Count;
for (int i = 0; i < count; i++) {
//carpeta
if (ftp->DirectoryListing->Items[i]->ItemType == ditDirectory) {
RemoveFTPDir (ftp->DirectoryListing->Items[i]->FileName, ftp, m);
// delete(items[i]) ==dir;
}
if (ftp->DirectoryListing->Items[i]->ItemType == ditFile) {
ftp->Delete(ftp->DirectoryListing->Items[i]->FileName);
// delete(items[i])==file;
}
}
} |
Saludos, Bosoft |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Vie 12 Nov, 2010 4:24 pm Asunto: |
|
|
bosoft
| Cita: | | Tengo una duda ¿el count contiene solo los elementos dentro de la carpeta? si tiene también los que están dentro de las subcarpetas, no he dicho nada y no se por donde pillarlo |
El count solo tiene el numero de elementos que están en la carpeta actual.
Ahora, si analizo tu codigo me encuentro con un problema
es el siguiente
carpeta1->fichero
carpeta2
entre a carpeta1
llame a la funcion
count = 1
elimino fichero
......y salgo de la funcion
entonces se quedan carpeta1 sin ficheros y carpeta2
es decir no cumpli mi objetivo. _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 12 Nov, 2010 4:40 pm Asunto: |
|
|
debe haber algún "fallito" en el código
veamos: llamas por primera vez a remove
ftp->DirectoryListing->Count =3:
carpeta1->fichero
fichero2
carpeta2
i=0;
carpeta1
en el for entra a otro remove, borra archivo y sale
borra dir,
i=1
borra fichero2
i=2
entra en carpeta2 y sale
borra carpeta2
y fin del for
Debe funcionar perfectamente
En cuanto a tu post, debes seguir ejecutando hasta que vuelvas al sitio donde se llamó el remove por primera vez, puesto que si haces un break, en el ejemplo, como la función remove ha sido llamada desde el interior de remove, la primera remove no ha terminado su ejecución
Saludos, Bosoft |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Vie 12 Nov, 2010 5:04 pm Asunto: |
|
|
Parece que no nos entendemos...
Recurda que cada vez que se llama a la funcion ocurre lo siguiente:
1-Se va al direcorio Dir
2-Se lista el directorio
3-Se almacena la cantidad de items encontrados
4-Se recorren los items etc
Teniendo esto si el item es carpeta se llama nuevamente a la funcion y nuevamente los pasos anteriores por lo que cambia de directorio , se lista el nuevo directorio y se crea un count con la cantidad de items, es decir el for anterior ya no existe y no hay forma de dar marcha atras si no se llama a la funcion cuando se elimina un fichero o cuando los items = 0; _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 12 Nov, 2010 7:40 pm Asunto: |
|
|
| ifrit escribió: | Parece que no nos entendemos...
Recurda que cada vez que se llama a la funcion ocurre lo siguiente:
1-Se va al direcorio Dir
2-Se lista el directorio
3-Se almacena la cantidad de items encontrados
4-Se recorren los items etc
Teniendo esto si el item es carpeta se llama nuevamente a la funcion y nuevamente los pasos anteriores por lo que cambia de directorio , se lista el nuevo directorio y se crea un count con la cantidad de items, es decir el for anterior ya no existe y no hay forma de dar marcha atras si no se llama a la funcion cuando se elimina un fichero o cuando los items = 0; |
Correcto excepto | Cita: | | es decir el for anterior ya no existe y no hay forma de dar marcha atras si no se llama a la función cuando se elimina un fichero o cuando los items = 0 |
El for anterior SI existe, aunque este latente. Siempre retrocederá una función al acabar la actual y terminará lo que estaba haciendo. Pero si la vuelves a llamar puedes anidar demasiadas funciones y ahí tienes el problema
Prueba el código y me dices
Saludos, bosoft |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Lun 15 Nov, 2010 5:10 pm Asunto: |
|
|
Hola quiero agradecer a bosoft por la ayuda, no sabia que las funciones recursivas almacenaran el ciclo anterior y el suguiente, etc. Bueno como no pude implementar la funcion para eliminar una carpeta lo que hice fue una para recorrer una carpeta, que hasta el momento me ha funcionado muy bien y luego elimino de otra forma...para mi ver algo rustico pero como necesitaba tambien recorrer un ftp ya esta todo listo. Aca dejo lo que hago, por si a alguien le interesa.
funcion listar carpeta y subcarpetas en ftp
| Código: | void Listar2(String Dir, TIdFTP * ftp, TMemo * m, TStringList * sl){
ftp->Noop();//send keep alive to ftp
static String mainDir = Dir;
ftp->ChangeDir(Dir);
ftp->List("", true);
int countItem = ftp->DirectoryListing->Count;
if (countItem == 0){
if (ftp->RetrieveCurrentDir() == mainDir){
return;
}
else {
ftp->ChangeDirUp();
ftp->List("", true);
//Listar2(ftp->RetrieveCurrentDir(), ftp, m, sl);
}
}
for (int i = 0;i <countItem>RetrieveCurrentDir() + "/" + ftp->DirectoryListing->Items[i]->FileName;
if (ftp->DirectoryListing->Items[i]->ItemType == ditDirectory){
//carpeta
if (sl->IndexOf(a + "/") == -1){
sl->Add(a + "/");
Listar2(a, ftp, m, sl);
}
}
else if (ftp->DirectoryListing->Items[i]->ItemType == ditFile){
//fichero
if (sl->IndexOf(a) == -1){
sl->Add(a);
}
}
//ultimo item
if (i + 1 == countItem){
if (ftp->RetrieveCurrentDir() == mainDir){
return;
}
else {
ftp->ChangeDirUp();
ftp->List("", true);
//Listar2(ftp->RetrieveCurrentDir(), ftp, m, sl);
}
}
} //fin for
} | ]
y la utilizo de la siguiente forma para eliminar la carpeta deseada.
| Código: | TStringList * sl = new TStringList();
Listar2("/x", IdFTP1, Memo1, sl);
//borrar ficheros
for (int i = sl->Count-1; i >= 0; i--) {
if (sl->Strings[i][sl->Strings[i].Length()] != '/'){
IdFTP1->Delete(sl->Strings[i]);
sl->Delete(i);
}
}
//borrar dir
for (int i = sl->Count-1; i >= 0; i--) {
IdFTP1->RemoveDir(sl->Strings[i]);
}
//borrar carpeta
IdFTP1->ChangeDir("/");
IdFTP1->RemoveDir("/x");
delete sl; |
_________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|