Ir al contenido


Foto

problemas con funcion recursiva


  • Por favor identifícate para responder
9 respuestas en este tema

#1 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 10 noviembre 2010 - 03:23

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



cpp
  1. void list (String Dir, TIdFTP * ftp, TMemo *m){
  2. static String mainDir = Dir;
  3. ftp->ChangeDir(Dir);
  4. ftp->List("",true);
  5. int count = ftp->DirectoryListing->Count;
  6. if (count == 0) {
  7.               String dir = ftp->RetrieveCurrentDir();
  8.               ftp->ChangeDirUp();
  9.               ftp->RemoveDir(dir);
  10.       //main Dir = Dir = "/x
  11.               String a =ftp->RetrieveCurrentDir();
  12.               if (ftp->RetrieveCurrentDir() == mainDir) {
  13.                   return ; }
  14.               list (ftp->RetrieveCurrentDir(), ftp, m);
  15.         }else{
  16.             for (int i = 0; i < count; i++) {
  17.               //carpeta
  18.               if (ftp->DirectoryListing->Items[i]->ItemType == ditDirectory) {
  19.                   list (ftp->DirectoryListing->Items->FileName, ftp, m);   
  20.                 }
  21.                 if (ftp->DirectoryListing->Items->ItemType == ditFile) {
  22.                   ftp->Delete(ftp->DirectoryListing->Items->FileName);
  23.                   list (ftp->RetrieveCurrentDir(), ftp, m);
  24.                 }
  25.             }
  26.           }
  27. }


Espero me puedan ayudar . Slaudos y gracias



edito: Me tove la libertad de acomodar tu codigo para que se entienda.
  • 0

#2 Mixel Adm

Mixel Adm

    Member

  • Miembros
  • PipPip
  • 23 mensajes
  • LocationChilangolandia

Escrito 10 noviembre 2010 - 03:49



cpp
  1. void list (String Dir, TIdFTP * ftp, TMemo *m){
  2.   static String mainDir = Dir;
  3.   ftp->ChangeDir(Dir);   
  4.   ftp->List("",true);
  5.   int count = ftp->DirectoryListing->Count;
  6.   if (count == 0) {     
  7.               String dir = ftp->RetrieveCurrentDir();     
  8.               ftp->ChangeDirUp();     
  9.               ftp->RemoveDir(dir);
  10.           //main Dir = Dir = "/x     
  11.               String a =ftp->RetrieveCurrentDir();     
  12.               if (ftp->RetrieveCurrentDir() == mainDir) {     
  13.                   return ;          }           
  14.               list (ftp->RetrieveCurrentDir(), ftp, m);   
  15.         }else{     
  16.             for (int i = 0; i < count; i++) {       
  17.               //carpeta       
  18.               if (ftp->DirectoryListing->Items->ItemType == ditDirectory) {           
  19.                   list (ftp->DirectoryListing->Items->FileName, ftp, m);           
  20.                 }       
  21.                 if (ftp->DirectoryListing->Items->ItemType == ditFile) { 
  22.                   ftp->Delete(ftp->DirectoryListing->Items->FileName);
  23.                   list (ftp->RetrieveCurrentDir(), ftp, m);
  24.                 }
  25.             }
  26.           }
  27. }



Tu código siempre va a listar el directorio "", esa llamada la debes de hacer desde fuera de la función, sino lo unico que vas a conseguir es acabarte la pilla.

ftp->List("",true);

Saludos
*editado porque no me fije que en el código no hay formato.
  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 10 noviembre 2010 - 03:59

Echando un vistazo rápido al código me parece extraño que pases como parámetro el objeto "ftp". Ten en cuenta que primero creas una lista con el método "List" pero luego cada vez que llamas al método "List" desde otra función estas cambiando la lista original no creando una nueva.
  • 0

#4 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 10 noviembre 2010 - 04:53

Hola amigos, parace que no me hice entender por llamarle a la funcion list que es el mimso nombre de la funcion List del ftp. Aca les dejo la misma funcion pero con otro nombre espero que asi me pueda hacer entender.


cpp
  1. void RemoveFTPDir (String Dir, TIdFTP * ftp, TMemo *m){  static String mainDir = Dir;
  2.   ftp->ChangeDir(Dir);   
  3.   ftp->List("",true);
  4.   int count = ftp->DirectoryListing->Count;
  5.   if (count == 0) {     
  6.               String dir = ftp->RetrieveCurrentDir();     
  7.               ftp->ChangeDirUp();     
  8.               ftp->RemoveDir(dir);
  9.           //main Dir = Dir = "/x     
  10.               String a =ftp->RetrieveCurrentDir();     
  11.               if (ftp->RetrieveCurrentDir() == mainDir) {     
  12.                   return ;          }           
  13.               RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m);   
  14.         }else{     
  15.             for (int i = 0; i < count; i++) {       
  16.               //carpeta       
  17.               if (ftp->DirectoryListing->Items->ItemType == ditDirectory) {           
  18.                   RemoveFTPDir (ftp->DirectoryListing->Items->FileName, ftp, m);           
  19.                 }       
  20.                 if (ftp->DirectoryListing->Items->ItemType == ditFile) { 
  21.                   ftp->Delete(ftp->DirectoryListing->Items->FileName);
  22.                   RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m);
  23.                 }
  24.             }
  25.           }
  26. }


Mixel Adm, gracias por responder sucede que no listo el directorio "", el TIdFTP al listar de la forma que lo hago lo que hace es ftp->List("",true) 1er paramentro quiere decir que puede ser ficheros o directorios o links o cualquier cosa, es decir una lista completa de todo lo que halla en CurrentDir y el 2do paramentro quiere decir que obtenga los detalles de lo que se obtiene en la lista como "nombre,tamaño,tipo,atributo,etc".



  • 0

#5 Mixel Adm

Mixel Adm

    Member

  • Miembros
  • PipPip
  • 23 mensajes
  • LocationChilangolandia

Escrito 10 noviembre 2010 - 05:25

Que tal ifrit.

Creo que aquí esta el problema.
supongamos que tenemos el directorio /datos/prueba y lo queremos eliminar, asumiendo que esta vacio tu funcion haria lo siguiente (una muy mala corrida de escritorio):

Dir  = '/datos/prueba'
entrando mainDir = '/datos/prueba'
cambiamos al directorio
cd /datos/prueba
luego count = 0 *
dir =  '/datos/prueba' ** dir = RetrieveCurrentDir;
cd .. ****ChangeDirUp();
delete /datos/prueba ***RemoveDir(dir);
a = /datos *****RetrieveCurrentDir();
si  /datos == /datos/prueba  ***********RetrieveCurrentDir() == mainDir
**esto nunca se cumple.
                  return ;     

**si no, elimina el direcotorio actual  es decirveCurrentDir(), ftp, m);   
        RemoveFTPDir (ftp->RetrieveCurrentDir(), ftp, m);

fin.


creo que lo que deberias de probar es si dir == mainDir , lo cual si te daría la solución deseada

Saludos cordiales.
  • 0

#6 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 10 noviembre 2010 - 06:12

Mixwl Adm, gracias por responder pero no. En dir solo se almacena el directorio donde estoy parado en ese momento para no perder la direccion cuando haga un ChangeDirUp y luego eliminar el valor de dir. Y si el caso si se cumple, lo digo porque ya lo pense bien, y ademas en modo debug lo he visto como paso por el return; pero luego brinca para la lineaif(listItem->ItemType == ditDirectory) {inexplicablemente....De todos modos seguire probando opciones , pero creo que es la utilizacion de la recursividad o algo porque aun no entiendo.un saludo
  • 0

#7 Mixel Adm

Mixel Adm

    Member

  • Miembros
  • PipPip
  • 23 mensajes
  • LocationChilangolandia

Escrito 10 noviembre 2010 - 08:30

Mixwl Adm, gracias por responder pero no. En dir solo se almacena el directorio donde estoy parado en ese momento para no perder la direccion cuando haga un ChangeDirUp y luego eliminar el valor de dir. Y si el caso si se cumple, lo digo porque ya lo pense bien, y ademas en modo debug lo he visto como paso por el return; pero luego brinca para la lineaif(listItem->ItemType == ditDirectory) {inexplicablemente....De todos modos seguire probando opciones , pero creo que es la utilizacion de la recursividad o algo porque aun no entiendo.un saludo


Bueno, el intento se hizo.

Saludos
  • 0

#8 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 11 noviembre 2010 - 05:44

Mixel Adm tienes toda la razon, ayer cuando te respondi lo hice casi sin analizar tu respuesta, ya casi era la hora de irme en el trabajo....disculpa!Como bien dices es si dir == mainDir...te dire que si se cumple, pero aun con el return no me sale de la funcion y eso me extraña mucho, porque a mi entender con un return se deberia salir sin mas no?Espero me puedan ayudar pues no se que mas hacer....la funcion corre muy bien solo que no sale de ella y vuelve a una de las condiciones dentro del ciclo for sin mas..... :|
  • 0

#9 Mixel Adm

Mixel Adm

    Member

  • Miembros
  • PipPip
  • 23 mensajes
  • LocationChilangolandia

Escrito 11 noviembre 2010 - 10:08

podrias probar algo como esto:




cpp
  1. void RemoveFTPDir (String Dir, TIdFTP * ftp, TMemo *m){ 
  2. ftp->ChangeDir(Dir);
  3.       ftp->List("",true); 
  4. int count = ftp->DirectoryListing->Count;
  5. for (int i = 0; i < count; i++) { 
  6.   if ( ftp->DirectoryListing->Items->ItemType == ditFile) {
  7.     ftp->Delete(ftp->DirectoryListing->Items->FileName);   
  8.              
  9. } else
  10. {
  11.     RemoveFTPDir (ftp->DirectoryListing->Items->FileName, ftp, m);
  12. }
  13.   sleep(500);
  14.   ftp->DirectoryListing->Items->nextItem;
  15. }
  16.  
  17. ftp->ChangeDirUp();
  18. ftp->RemoveDir(Dir);
  19. }



*** ftp->DirectoryListing->Items->nextItem;
Desconosco como funcione el objeto DirectoryListing pero creo que deberias de cambiar de objeto en cada iteracion.

*** sleep(500);
Y al ser ftp, seria convieniente que dejaras al servidor hacer su trabajo y reportartelo, para no hacerle un flooding de instrucciones.

Saludos
  • 0

#10 ifrit

ifrit

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 105 mensajes
  • LocationLa Habana, Cuba

Escrito 15 noviembre 2010 - 10:09

Hola quiero agradecer a Mixel Adm 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

cpp
  1. void Listar2(String Dir, TIdFTP * ftp, TMemo * m, TStringList * sl){
  2.    
  3.   ftp->Noop();//send keep alive to ftp
  4.    
  5.   static String mainDir = Dir;
  6.   ftp->ChangeDir(Dir);
  7.   ftp->List("", true);
  8.  
  9.   int countItem = ftp->DirectoryListing->Count;
  10.  
  11.   if (countItem == 0){
  12.       if (ftp->RetrieveCurrentDir() == mainDir){
  13.         return;
  14.       }
  15.       else {
  16.         ftp->ChangeDirUp();
  17.         ftp->List("", true);
  18.         //Listar2(ftp->RetrieveCurrentDir(), ftp, m, sl);
  19.       }
  20.   }
  21.  
  22.   for (int i = 0;i <countItem>RetrieveCurrentDir() + "/" + ftp->DirectoryListing->Items[i]->FileName;
  23.  
  24.       if (ftp->DirectoryListing->Items[i]->ItemType == ditDirectory){
  25.         //carpeta
  26.         if (sl->IndexOf(a + "/") == -1){
  27.             sl->Add(a + "/");
  28.             Listar2(a, ftp, m, sl);
  29.         }
  30.       }
  31.       else if (ftp->DirectoryListing->Items[i]->ItemType == ditFile){
  32.         //fichero
  33.         if (sl->IndexOf(a) == -1){
  34.             sl->Add(a);
  35.         }
  36.       }
  37.       //ultimo item
  38.       if (i + 1 == countItem){
  39.         if (ftp->RetrieveCurrentDir() == mainDir){
  40.             return;
  41.         }
  42.         else {
  43.             ftp->ChangeDirUp();
  44.             ftp->List("", true);
  45.             //Listar2(ftp->RetrieveCurrentDir(), ftp, m, sl);
  46.         }
  47.       }
  48.  
  49.   } //fin for
  50.  
  51. }

y la utilizo de la siguiente forma para eliminar la carpeta deseada.


cpp
  1. TStringList * sl = new TStringList();    Listar2("/x", IdFTP1, Memo1, sl);
  2.  
  3.  
  4.  
  5.   //borrar ficheros
  6.   for (int i = sl->Count-1; i >= 0; i--) {
  7.       if (sl->Strings[i][sl->Strings[i].Length()] != '/'){
  8.         IdFTP1->Delete(sl->Strings[i]);
  9.         sl->Delete(i);
  10.       }
  11.   }
  12.  
  13.   //borrar dir
  14.   for (int i = sl->Count-1; i >= 0; i--) {
  15.       IdFTP1->RemoveDir(sl->Strings[i]);
  16.   }
  17.  
  18.     //borrar carpeta
  19.   IdFTP1->ChangeDir("/");
  20.   IdFTP1->RemoveDir("/x");
  21.  
  22.  
  23.   delete sl;



No sé porque sale el código desorganizado?
[/]
  • 0




IP.Board spam blocked by CleanTalk.