• Viernes 29 de Marzo de 2024, 10:25

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Temas - krnl64

Páginas: [1] 2
1
C/C++ / INVALID_HANDLE redireccionando cin,cout,cerr
« en: Jueves 9 de Septiembre de 2010, 21:02 »
Hola,  estoy escribiendo una pequeña clase para abrir una consola en programas con interfaz gráfica y usarla para emitir información de depuración.
Por comodidad, intento redirigir los flujos de la consola para poder usar cin, cout y cerr en vez de apis para leer y escribir en ella
El código que les presento yo diria que es correcto, pero no se comporta bien en ejecución.

Si hago un cin, ya no escribe nada en pantalla al usar cout. Sólo si uso cerr y escribe todo lo que haya en el buffer.
En vista de estos fallos, uso GetLastError después de hacer cin, y me dice INVALID_HANDLE_VALUE.
No entiendo por qué se cierra el handle.

Edit:
Pruebas hasta ahora sin resultado:
1º Obtener el handles de entrada, salida y error con GetStdHandle en el constructor. Intentar restaurarlos con SetConsoleActiveScreenBuffer. cout sigue sin escribir en consola.
2º Cerrar el handle de salida con CloseHandle, volver a abrirlos con GetStdHandle y usar cout. Aqui GetLastError dice que no hay error, pero no se escribe nada en consola
3º Abrir los flujos de consola CONIN$,CONOUT$,CONERR$ con CreateFile. Restaurarlos con SetConsoleActiveScreenBuffer y usar cout. GetLastError dice INVALID_HANDLE y no se escribe nada en consola

Pueden decirme qué es lo que hago mal ?

PD: uso W Xp SP3 y VC++ 2008

Gracias

console.h
Código: C++
  1.  
  2. // console.h
  3. #ifndef __CONSOLE_H__
  4. #define __CONSOLE_H__
  5.  
  6. #include <iostream>
  7. #include <fstream>
  8.  
  9. using std::cout;
  10. using std::cin;
  11. using std::cerr;
  12.  
  13. using std::streambuf;
  14. using std::ofstream;
  15. using std::ifstream;
  16.  
  17.  
  18. class console
  19. {
  20.  
  21.     private:
  22.    
  23.         ofstream n_cout;
  24.         ofstream n_cerr; // new streams
  25.         ifstream n_cin;
  26.  
  27.         streambuf* old_cout;
  28.         streambuf* old_cerr; // old streams
  29.         streambuf* old_cin;
  30.  
  31.     public:
  32.    
  33.         console();
  34.         ~console();
  35.  
  36.         void hide();
  37.         void show(); // not implemented yet
  38. };
  39. #endif
  40.  
  41.  

console.cpp
Código: C++
  1.  
  2. #include "console2.h"
  3. #include <windows.h>
  4.  
  5. console::console()
  6. {
  7.    
  8.     // create a console window
  9.     AllocConsole();
  10.  
  11.     // redirect cout to console window
  12.     this->old_cout = cout.rdbuf(); 
  13.     this->n_cout.open("CONOUT$");   
  14.     cout.rdbuf( this->n_cout.rdbuf() );
  15.    
  16.     // redirect cerr
  17.     this->old_cerr = cerr.rdbuf();
  18.     this->n_cerr.open("CONOUT$");
  19.     cerr.rdbuf( this->n_cerr.rdbuf() );
  20.  
  21.     // redirect cin
  22.     this->old_cin = cin.rdbuf();
  23.     this->n_cin.open("CONIN$");
  24.     cin.rdbuf( this->n_cin.rdbuf() );
  25.    
  26. }
  27.  
  28. console::~console()
  29. {
  30.     // restore streams
  31.     cin.rdbuf( this->n_cin.rdbuf() );
  32.     cerr.rdbuf( this->n_cerr.rdbuf() );
  33.     cout.rdbuf( this->n_cout.rdbuf() );
  34.    
  35.   // free console resources
  36.   FreeConsole();
  37. }
  38.  
  39.  

// main.cpp
Código: C++
  1.  
  2.  
  3. #include <windows.h>
  4.  
  5. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  6. {
  7.  
  8. // all WNDCLASSEX, RegisterClassEx,CreateWindow, etc stuff
  9.  
  10.  console c;
  11.  int number = 0;
  12.  
  13. cout << "n cout works";
  14. cerr << "n cerr works";
  15. cin >> number; // cin works
  16.  
  17. DWORD error = GetLastError(); // INVALID_HANDLE_VALUE ¿ por qué ?
  18.  
  19. cout << "n The number is: " << number;  // Esto ya no funciona
  20.  
  21. cerr << number; // ahora escribe todo lo que haya en el buffer
  22. }
  23.  
  24.  

2
C/C++ / Sobrecargar operador = con punteros
« en: Jueves 22 de Julio de 2010, 20:44 »
Hola, he escrito una clase lista cuya interfaz declaro a continuación
Código: C++
  1.  
  2. class linkedlist
  3.     {
  4.    
  5.         public:
  6.        
  7.             linkedlist(void); // default constructor
  8.            
  9.             linkedlist (const linkedlist& tocopy); // copy constructor
  10.                
  11.             ~linkedlist(); // destructor
  12.            
  13.              bool insert ( const int value ); // insert element            
  14.            
  15.              bool remove ( void ); // remove first element                     
  16.            
  17.              bool is_empty ( void ) const; // returns if the list is empty
  18.            
  19.              int size  ( void ) const; // return list size
  20.            
  21.              linkedlist& operator = (const linkedlist& list); // overload = operator       
  22.              
  23.              int& operator [] ( const int index ) const; // overload subscript operator
  24.    
  25.         private:
  26.        
  27.             struct node
  28.             {
  29.                 int value;  // node struct
  30.                 node* next;
  31.             }; 
  32.            
  33.             int elements;     // amount of elements
  34.             node* firstnode; // first node
  35.                                
  36.     };
  37.  
  38.  

Lo que quiero conseguir es que cuando escriba esto

Código: C++
  1.  
  2.  linkedlist*  lista1 = NULL;
  3.  linkedlist* lista2 = NULL;
  4.  
  5. // creo lista1 con new
  6.  
  7. lista2 = lista1;
  8.  
  9.  
  10.  

no se copie tal cual el objeto, sino que se cree memoria para el y se copien los valores.
He probado a sobrecargar el operador = de esta manera
Código: C++
  1.  
  2. linkedlist& operator = (const linkedlist* &list);
  3.  
  4.  

pero no consigo que cuando se ejecuta la linea 7 entre en la funcion.

Alguien sabe como hacer esto ?

Gracias

3
C/C++ / Duda Destructores C++
« en: Miércoles 21 de Julio de 2010, 17:55 »
Hola, tengo un par de dudas acerca del comportamiento de los destructores.

Mirando http://www.parashift.com/c++-faq-lite/dtors.html  punto 11.11

dice que cuando cuando se destruye un objeto se llama automáticamente a los destructores de los miembros de los que esta compuesto.
Se refiere a los miembros que no son punteros  ?
Que ocurre si en el destructor pongo las variables miembro a su valor por defecto entonces ? ( por ejemplo pongo un entero a 0 o a NULL)

Editado : ya vi el fallo del code de antes

 A ver si me pueden esclarecer el tema un poco Gracias

4
C/C++ / Error reservar memoria dentro funcion
« en: Miércoles 10 de Febrero de 2010, 22:17 »
Hola amigos.
Estoy intentando reservar memoria para una variable externa a la función que la reserva.
Dentro de la función la reserva y la usa,pero al volver el codigo a donde hizo la llamada
falla.
Concretamente falla en la linea 17 de main.c
Por más que miro no sé donde está el fallo.
Pueden hecharme una mano ?
Gracias.

aleatorio.h
Código: C
  1.  
  2. void alsr(int **vector, int inicio, int fin, int cuantos);
  3.  
  4.  

aleatorio.c
Código: C
  1.  
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include "aleatorio.h"
  5.  
  6. void alsr(int **vector, int inicio, int fin, int cuantos)
  7. {
  8.     int *temporal=NULL;
  9.     int i;
  10.     int j;
  11.     int pos;
  12.     int lon;
  13.  
  14.  
  15.     lon=fin-inicio; 
  16.  
  17.     /*Pedir memoria para temporal.*/
  18.     temporal=(int*)malloc(lon*sizeof(int));
  19.  
  20.     if(temporal==NULL)
  21.         return;
  22.  
  23.     for(i=0;i<lon;i++)
  24.     {
  25.         *(temporal+i)=inicio+i; 
  26.     }
  27.  
  28.     /*Pedir memoria array externo*/
  29.     *vector=(int*)malloc(cuantos*sizeof(int));
  30.     if(vector==NULL)
  31.         return;
  32.  
  33.     /*Llenamos el vector de aleatorios*/
  34.     for(i=0;i<cuantos;i++)
  35.     {
  36.    
  37.         /* Si tengo mas de un elemento */
  38.         if(cuantos > 1)
  39.         {
  40.             pos=rand()%lon;
  41.             /*Copio el elemento de esa posicion al original*/
  42.             *(vector+i)=*(temporal+pos);
  43.        
  44.             /*Realmente atrasamos el elemento del array*/
  45.             for(j=pos;j<lon-1;j++)
  46.                 *(temporal+j)=*(temporal+j+1);
  47.  
  48.             /*Vamos eliminando el ultimo elemento*/
  49.             lon--;     
  50.             temporal=(int*)realloc(temporal,lon*sizeof(int));
  51.         }
  52.         else
  53.         {      
  54.             *(vector+i)=*(temporal);
  55.         }
  56.  
  57.     }
  58.  
  59.  
  60.     free(temporal);
  61.     temporal=0;
  62.  
  63.     return;
  64. }
  65.  
  66.  

main.c
Código: C
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "aleatorio.h"
  5.  
  6. #define cantidad 2
  7.  
  8. int main(int argc,char *argv[])
  9. {
  10.     int *tmp=0;
  11.     int i;
  12.  
  13.     alsr(&tmp,1,5,cantidad);
  14.  
  15.     for(i=0;i<cantidad;i++)
  16.     {
  17.         printf(" %d ",*(tmp+i));
  18.     }
  19. }
  20.  
  21.  
  22.  

5
HTML / Problema con codigo en IE8
« en: Lunes 25 de Enero de 2010, 14:29 »
Hola a todos, veran he desarrollado un calendario en html / js (no esta acabado) y en firefox funciona.
Pero acabo de abrirlo en IE8 y me dice que tengo un error.
En concreto dice "Error desconocido en tiempo de ejecucion en Linea 28 caracter 3 en el archivo de js".
Por mas que reviso mi fuente no veo el error.
Les pongo el codigo a ver si pueden decirme donde esta el error.
Gracias

Web
Código: Text
  1.  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http]
  3.  
  4. Js (donde peta)
  5. [code=js] 
  6. function dmonth(iMonth, iYear)
  7. {
  8.     return 32 - new Date(iYear, iMonth, 32).getDate();
  9. }
  10.  
  11. function ponceldas()
  12. {
  13.     var celdas='';
  14.     var i;
  15.     var j;
  16.    
  17.         for(i=0;i<6;i++)
  18.         {
  19.             celdas+='<tr>';
  20.            
  21.             for(j=0;j<7;j++)
  22.                 celdas+='<td class="day"></td>';
  23.                
  24.             celdas+='</tr>';
  25.         }
  26.         document.getElementById('calendario').tBodies[0].innerHTML+=celdas;
  27.         pond(0,0);
  28. }
  29.  
  30. function pond(y,m)
  31. {
  32.  
  33. var celdas;
  34. var i;
  35. var maxdias;
  36. var dia=1;
  37. var day;
  38. var hoy;
  39.    
  40.     if (m==0 && y==0)
  41.     {
  42.         hoy=new Date();
  43.         day=hoy.getDate();
  44.         hoy.setDate(1);
  45.     }
  46.     else
  47.         hoy=new Date(parseInt(y),parseInt(m),1);
  48.        
  49.     // dias del mes actual
  50.     maxdias=dmonth(hoy.getMonth(),hoy.getFullYear());   
  51.     celdas=document.getElementById('calendario').tBodies[0].getElementsByTagName('td');
  52.    
  53.     // mes y año
  54.     document.getElementById('mes').selectedIndex=hoy.getMonth();
  55.     document.getElementById('anio').innerHTML='  '+hoy.getFullYear()+'  ';
  56.    
  57.     //vacio todas las celdas
  58.         for(i=0;i<celdas.length;i++)   
  59.             celdas[i].innerHTML='';
  60.  
  61.     // calculo el desplazamiento del dia de la semana en base al que js me da
  62.     for(i=(hoy.getDay()+6)%7;i < celdas.length;i++)
  63.     {
  64.         if (dia<=maxdias)
  65.         {
  66.             celdas[i].innerHTML=dia;
  67.             dia+=1;
  68.         }
  69.     }
  70.  
  71. }
  72. function pm()
  73. {
  74. pond(document.getElementById('anio').textContent,document.getElementById('mes').value);
  75. }
  76.  

6
VB .NET / Error con DirectCast y ArrayList
« en: Miércoles 16 de Diciembre de 2009, 18:06 »
Hola a todos.
Verán tengo un ArrayList en el que quiero meter varios tipos de objetos.
He heredado del control TextBox y le he añadido otra propiedad Tag llamada Tag2 para almacenar datos que necesite.

La declaracion del objeto que almacena el contenido de la propiedad es:
Código: vb.net
  1.  
  2. private _tag2 as Object
  3.  
  4.  

y la declaracion de la propiedad:

Código: vb.net
  1.  
  2.     <TypeConverter(GetType(StringConverter))> _
  3.     <Browsable(True), DescriptionAttribute("Propiedad Tag 2"), CategoryAttribute("EProperties")> _
  4.     Public Property Tag2() As Object
  5.         Get
  6.             Return (Me._tag2)
  7.         End Get
  8.         Set(ByVal value As Object)
  9.             Me._tag2 = value
  10.         End Set
  11.     End Property
  12.  
  13.  

Entonces, en la propiedad Tag2 almaceno el nombre del tipo al que quiero convertir el contenido Text de mi TextBox.

Queda asi:
Código: vb.net
  1.  
  2. micontrol.Text="12/12/1999"
  3. micontrol.Tag2="System.DateTime"
  4.  
  5.  

Entonces al añadir el item al ArrayList, esta sentencia me falla:
Código: vb.net
  1.  
  2. miarraylist.Add(DirectCast(micontrol.Text,Type.GetType(micontrol.Tag2.ToString()))
  3.  
  4.  

No es correcta la conversion ?
Cómo puedo solucionar esto ?

Gracias

7
C/C++ / [Código Fuente] Ahorcado Complicado
« en: Miércoles 16 de Septiembre de 2009, 02:47 »
Este es el codigo del juego del ahorcado pero en su forma complicada.
En el codigo fuente se usa la modularizacion punteros y la API de windows.

Un ejemplo muy didactico.

Autor: ++K

8
C/C++ / Duda con puntero
« en: Martes 15 de Septiembre de 2009, 18:25 »
Hola amigos, tengo un código que me está dando problemas.
Tengo un array de estructuras y quiero modificarlo dentro de una función por medio de punteros.
No entiendo por qué lo hago mal. Haber si pueden hecharme un cable, gracias

Código: C
  1.  
  2.  
  3. main.c
  4.  
  5. typedef struct
  6. {
  7. char nombre[20];
  8. int puntos;
  9. }ITEM;
  10.  
  11.  
  12. void func1(ITEM *persona, int longitud)
  13. {
  14.  
  15. char *nombres[]={"Fernando","Pablo"};
  16. int i;
  17.    
  18.         for(i=0;i<longitud;i++)
  19.         {
  20.                strcpy(&(*(persona+i)).nombre,*(nombres+i));  // aqui falla
  21.                 &(*(persona+i)).puntos=30;
  22.         }
  23.  
  24. int main( int argc, char *argv[])
  25. {
  26.    
  27.  ITEM listaitem[]=
  28.  {
  29.  {"Manuel",20},{"Fernando",10}
  30.  };
  31.  
  32.  int i;
  33.  
  34.     func1(listaitem,2);
  35.  
  36.    
  37.     for(i=0;i<2;i++)
  38.     {
  39.         printf("n %s %d",listaitem[i].nombre,listaitem[i].puntos);
  40.     }
  41.    
  42.    
  43. }
  44.  
  45.  

9
C/C++ / Problema redimensionando array de strings
« en: Lunes 1 de Junio de 2009, 19:06 »
Hola a todos.
Estoy intentando hacer una función que recibe un array de strings y dentro copia ese array a uno temporal y lo redimensiono a n-1 para luego seguir
trabajando con él.
Pero no me lo hace bien. Les pongo el code y les comento:
Código: C
  1.  
  2. void redimlista(char **lista_palabras,const int longitud_lista)
  3. {
  4. char **lista_temporal;
  5. int i;
  6. int num;
  7. int longitud_lista_temporal;
  8. char palabra[8];
  9.  
  10. /* Pido memoria para almacenar los punteros a cadena */
  11.     lista_temporal=(char**)calloc(longitud_lista,sizeof(char*));
  12.  
  13.     /* Voy a copiar toda la lista de palabras al array temporal */
  14.     for(i=0;i<longitud_lista;i++)
  15.     {
  16.         /* Reservo memoria para almacenar la cadena 8 porque 8 es la longitud máxima de las palabras */
  17.         *(lista_temporal+i)=(char*)calloc(8,sizeof(char));             
  18.        
  19.         /*Copio la cadena */
  20.         strcpy(*(lista_temporal+i),*(lista_palabras+i));
  21.     }   
  22.  
  23.         /* Guardo la longitud del array de palabras */
  24.         longitud_lista_temporal=longitud_lista;
  25.  
  26.        /* Elijo una palabra aleatoriamente de la lista de palabras */
  27.         num=rand()%longitud_lista_temporal;
  28.        
  29.         /* Copio la palabra elegida */
  30.         strcpy(palabra,*(lista_temporal+num));
  31.  
  32.                 /* Adelanto todos los elementos un lugar */
  33.                 for(i=num;i<longitud_lista_temporal-1;i++)
  34.             *(lista_temporal+i)=*(lista_temporal+i+1);
  35.  
  36.               /* Linea problematica */
  37.               free(*(lista_temporal+i));
  38.  
  39.              longitud_lista_temporal--;
  40.        
  41.          lista_temporal=(char**)realloc(lista_temporal,longitud_lista_temporal*sizeof(char*));
  42.  
  43.           /* ....  mas codigo... */
  44.            
  45. }
  46.  
  47.  

El código de la línea 37 es el que me da problemas.
Por ejemplo,si a la función le paso un array de 5 palabras al hacer el free, me libera la memoria de los elementos 4 y 5 en vez de solo el 5º.
Es decir:

Antes del free
Código: C
  1.  
  2. *(lista_temporal+3)="pepe"
  3. *(lista_temporal+4)="paco"
  4.  
  5.  

Después del free
Código: C
  1.  
  2. *(lista_temporal+3)= liberado
  3. *(lista_temporal+4)= liberado
  4.  
  5.  

Y lo que quiero conseguir es:
Código: C
  1.  
  2. *(lista_temporal+3)= "pepe"
  3. *(lista_temporal+4)= liberado
  4.  
  5.  
para poder redimensionar después con realloc.
Cómo puedo arreglar esto ?
Gracias

10
C/C++ / Error en función y no se por qué
« en: Lunes 1 de Junio de 2009, 01:29 »
Hola a todos,
Hice una función para trabajar con un array de strings pero no sé por qué no me funciona.
Les pongo el code:
Código: C
  1.  
  2. void test( char **aray,int size)
  3. {
  4.  
  5. char **tmp;
  6. int i=0;
  7.  
  8. tmp=(char**)calloc(size,sizeof(char*));
  9.  
  10. for(i=0;i<size;i++)
  11. {
  12.     *(tmp+i)=(char*)calloc(strlen(*(aray+i)+1),sizeof(char));   
  13.     //strcpy(*(tmp+i),*(aray+i));
  14.     memcpy(*(tmp+i),*(aray+i),strlen(*(aray+i)+1));
  15. }
  16.    
  17.  
  18. for(i=0;i<size;i++)
  19. {
  20.     free(*(tmp+i));
  21. }
  22.  
  23. free(tmp);
  24.  
  25.  
  26.  

Si uso la declaración de la linea 14, no sé por qué no copia bien la cadena y si uso la declaración de la línea 13 me peta al hacer free.
Pueden decirme que hago mal ?
Gracias.

11
C/C++ / Duda funcion con nº de parametros variables
« en: Miércoles 27 de Mayo de 2009, 22:24 »
Hola a todos.
Hace un tiempo les pregunte acerca de como hacer un scanf personalizado.
Me dijeron como podia leer los datos correctamente con fgets y sscanf. Hasta aqui ok.
Bueno, hice la función y me dio por iniciar la variable referenciada dentro de la función pero no me lo hace bien.
Les enseño el codigo y les explico:

Código: C
  1.  
  2.   
  3. void myscanf(const char *formato,...)
  4. {
  5.  
  6. char bufferinterno[80];
  7. int vars=0;
  8.  
  9.  /* codigo para contar los argumentos de entrada
  10.    basicamente cuento los % para saber las variables
  11.   que tengo que leer
  12.   (almacenado en vars)
  13. */
  14.  
  15. /* Inicio el buffer interno */
  16. memset(bufferinterno,0,sizeof(bufferinterno));
  17.  
  18. /* intento iniciar la variable referenciada */
  19. memset(*(&format+vars),0,sizeof(*(&format+vars)));
  20.  
  21. fgets(....);
  22. sscanf(...);
  23.  
  24. }
  25.  
  26.  
  27.  

Lo que me ocurre es que cuando hago esto

Código: C
  1.  
  2. char buffer[50];
  3. myscanf("%s",buffer);
  4.  
  5.  

El memset de la linea 19 no inicia correctamente el buffer porque *(&format+vars) apunta al primer caracter del buffer y no hay forma de saber cuál es su tamaño para iniciarlo correctamente.

Hay alguna forma de saber cuanto ocupa la variable referenciada o el unico remedio seria pasarle a la función su tamaño para iniciarla correctamente ?
O inciarla antes de pasarsela a la función.

Gracias

12
Hardware / Duda con placa base y memoria
« en: Miércoles 27 de Mayo de 2009, 03:48 »
Hola a todos, les comento mi duda:

Tengo una placa Asus P5KPL-VM/S y un micro Core 2 Duo E6750.
Hasta ayer tenía instalados 2 modulos de 1 Gb DDR2 667 Mhz Kingston.
Fenómeno hasta aqui.
Ahora he comprado 2 modulos de 1 GB DDR2 a 800 Mhz Kingston y se los he puesto.

Las especificaciones de mi placa dicen:

Front Side Bus: 1333(overclock)1066,800 Mhz
Memory: 4Gb 667/800Mhz Dual Channel

Ahora corro el Everest y me dice:

   Propiedades del bus principal:
      Tipo de bus                                     Intel AGTL+
      Ancho de bus                                   64 bit
      Reloj real                                        333 MHz (QDR)
      Reloj efectivo                                  1333 MHz
      Ancho de banda                                10664 MB/s

    Propiedades del bus de memoria:
      Tipo de bus                                       Dual DDR2 SDRAM
      Ancho de bus                                     128 bit
      Relación DRAM:FSB                            12:10
      Reloj real                                          400 MHz (DDR)
      Reloj efectivo                                    800 MHz
      Ancho de banda                                  12797 MB/s

No entiendo por qué me hace cuello de botella si la el manual de la placa dice que soporta la DDR2 800Mhz.
Pueden decirme que hacer para que vayan a la par la memoria y el fsb ?
Gracias

13
C/C++ / corrupcion de pila leer caracter
« en: Lunes 25 de Mayo de 2009, 22:16 »
Hola, quiero leer un carácter de entre una serie de caracteres permitidos con scanf.

Por qué me falla este code si le estoy diciendo que lea solo 1 caracter ?
Código: C
  1.  
  2.  
  3. unsigned char caracter=0;
  4.  
  5. scanf("%1[1234]",&caracter)
  6.  
  7.  

Gracias.

14
C/C++ / fallo intentando hacer scanf personalizado
« en: Jueves 14 de Mayo de 2009, 21:30 »
Hola a todos.

Estoy intentando hacer un wrapper para scanf. Mi intencion es limpiar el buffer de consola antes y despues ejecutar la funcion scanf original.

El code es este:
Código: C
  1.  
  2.  
  3. void myscanf(const char *format,...)
  4. {
  5.  
  6.     va_list args;
  7.         char c;
  8.                          
  9.             while((c = getchar()) != EOF); 
  10.         va_start(args,format);
  11.         scanf(format,args);
  12.         va_end(args);
  13. }
  14.  
  15.  


El caso es que a scanf no le llegan los argumentos .... y no se por qué.

Puede alguien decirme que he hecho mal ?

PD: tengo todos los includes.
Gracias

15
C# / Problema al intentar repintar control
« en: Martes 25 de Noviembre de 2008, 09:23 »
Hola a todos, tengo un problema que no sé solucionar con un control que me estoy creando.
Verán, estoy intentando hacerme un control para hacer mapas para rpg's a base de tiles.
Comencé a hacerlo como una clase que hereda de un panel y dentro otro panel que es donde dibujo una malla.
No usé el diseñador, y lo hice de esta manera porque asi el scroll me lo hace solo.
Bueno, pues hago el code, me pinta y todo muy bonito pero cuando la ventana pierde el foco, lo que he pintao dentro del 2º panel se pierde.
He intentando hookear el WndProc del panel interior, pero no se hacerlo.
Pueden decirme que puedo hacer para repintar el contenido del control ?
Les dejo aqui el code:
Código: Text
  1.  
  2.   class Grid2:Panel
  3.     {
  4.         Panel p2;
  5.                        
  6.         private int hcells;
  7.         private int vcells;
  8.        
  9.         private int theigth;
  10.         private int twidth;
  11.  
  12.         private const int WM_PAINT = 0xF;
  13.        
  14.    
  15.         public Grid2(int sizetile, int height, int width)
  16.         {
  17.             this.AutoScroll=true;
  18.             this.BorderStyle=BorderStyle.FixedSingle;
  19.             this.Width=600;
  20.             this.Height=600;
  21.            
  22.             // N1 de celdas
  23.             this.hcells=height;
  24.             this.vcells=width;
  25.            
  26.             this.twidth=sizetile;
  27.             this.theigth=sizetile;
  28.            
  29.            
  30.             p2=new Panel();
  31.            
  32.             p2.Height=this.vcells*this.theigth;
  33.             p2.Width=this.hcells*this.twidth;
  34.            
  35.             p2.Paint += new PaintEventHandler(p2_Paint);
  36.        
  37.            
  38.            
  39.             p2.MouseMove += new MouseEventHandler(p2_MouseMove);                                    
  40.             this.Controls.Add(p2);
  41.            
  42.            
  43.            
  44.            
  45.         }
  46.  
  47.         void p2_MouseMove(object sender, MouseEventArgs e)                
  48.         {
  49.        
  50.             if (e.Button==MouseButtons.Left) {
  51.        
  52.                     int x;
  53.                     int y;
  54.                    
  55.                     Panel p;
  56.                     Pen pn=new Pen(Color.Green,2);
  57.                     Graphics g;
  58.                    
  59.                         x=(e.X/32); // Averiguo en que casilla esta el raton
  60.                         y=(e.Y/32);
  61.                        
  62.                         g=((Panel)sender).CreateGraphics();
  63.                        
  64.                         // DrawRectangle (x,y(origen),ancho, alto)
  65.                         g.DrawRectangle(pn,new Rectangle(x*this.twidth,y*this.theigth,this.twidth,this.theigth));
  66.                      
  67.                         g.Dispose();
  68.             }
  69.         }
  70.        
  71.         #region Propiedades
  72.        
  73.         /// <summary>
  74.         /// Nº de celdas de ancho
  75.         /// </summary>
  76.         public int Hcells
  77.         {
  78.             get
  79.             {
  80.                 return(this.hcells);
  81.             }
  82.             set
  83.             {
  84.                 this.hcells=value;
  85.             }
  86.         }
  87.        
  88.        
  89.         /// <summary>
  90.         /// Nº de celdas de alto
  91.         /// </summary>
  92.         public int Vcells
  93.         {
  94.             get
  95.             {
  96.                 return(this.vcells);
  97.             }
  98.            
  99.             set
  100.             {  
  101.                 this.vcells=value;
  102.             }
  103.         }
  104.        
  105.        
  106.         /// <summary>
  107.         /// Alto del tile
  108.         /// </summary>
  109.         public int Theigth
  110.         {
  111.             get
  112.             {
  113.                 return(this.theigth);
  114.             }
  115.            
  116.             set
  117.             {
  118.                 this.theigth=value;
  119.             }            
  120.         }
  121.        
  122.         /// <summary>
  123.         /// Ancho del tile
  124.         /// </summary>
  125.         public int Twidth
  126.         {
  127.             get
  128.             {
  129.                 return(this.twidth);
  130.             }
  131.            
  132.             set
  133.             {
  134.                 this.twidth=value;
  135.             }
  136.         }
  137.        
  138.         #endregion
  139.  
  140.         void p2_Paint(object sender, PaintEventArgs e)
  141.         {
  142.                      
  143.             int x;
  144.             int y;
  145.        
  146.      
  147.            
  148.             Pen mypen=new Pen(Color.Gray);
  149.            
  150.                 // lineas verticales
  151.                  for (x=0;x<this.hcells*this.twidth; x+=this.twidth)
  152.                     e.Graphics.DrawLine(mypen,x,0,x, this.hcells*this.twidth);              
  153.              
  154.                 // lineas horizontales                        
  155.                for (y = 0; y < this.vcells * this.theigth; y += this.theigth)
  156.                     e.Graphics.DrawLine(mypen, 0, y, this.hcells * this.theigth, y);
  157.                                                                                
  158.                    e.Graphics.DrawRectangle(mypen, 1, 1, this.theigth * this.hcells - 2, this.twidth * this.vcells - 2);
  159.                    
  160.                
  161.         }
  162.        
  163.     }
  164. }
  165.  
  166.  

Gracias

16
VB .NET / Problema Con Thread
« en: Sábado 21 de Junio de 2008, 10:21 »
Hola a todos. Hice un programa que cuando captura una excepcion finaliza la app y  te crea un thread que te saca un topic de un chm (explicación del error).
El codigo que ejecuta el thread es este:

Código: Text
  1.  
  2.  
  3. Private Shared Sub Ayuda()
  4.  
  5.    Dim hp As New HelpProvider
  6.  
  7.                     hp.SetHelpNavigator(Me,HelpNavigator.Topic)
  8.  
  9.                     hp.SetHelpKeyWord(Me,60)
  10.  
  11.                     Help.ShowHelp(me,&#34;Help.chm&#34;)
  12.  
  13. end Sub
  14.  
  15.  
  16.  


Pero el thread no espera para terminar que el usuario cierre la ventana de ayuda que se abre.

No se me ocurre cómo hacer esto.

Pueden ayudarme ?

Gracias.

17
VB .NET / Duda Con Splashscreen
« en: Domingo 25 de Mayo de 2008, 16:03 »
Hola a todos.
Verán hice un programa un poco denso que necesita cargar bastantes datos antes de mostrar el form principal, asi que me hice una clase SplashScreen.

Mi clase crea un form, barra de progreso, un par de labels y hace fades al aparecer y desparecer.

Mi problema es que cuando la inicio, tengo que poder esperar a que el fade de aparicion se complete para poder mandarle datos y que actualize la progressbar.

Es decir, que el form  termine de aparecer en pantalla antes de hacer nada más.

Porque ahora mismo, tengo en el form_load del form principal una llamada a esa clase y despues todas las operaciones de carga del programa, pero cuando inicia la splashscreen inmediatamente sigue ejecutando por la instruccion siguiente sin esperar a que el timer que hace el fade de aparicion se pare.

Pueden decirme como puedo hacer eso ?

Gracias

18
VB .NET / Clase Comparador (ordenar Columnas Listview)
« en: Miércoles 7 de Mayo de 2008, 06:02 »
Alguna vez quisieron ordenar el contenido de un Listview en modo Details al pinchar encima del nombre de la columna y que se ordenara segun su contenido ?

Pues esta clase que les dejo les ayudará.

Puede ordenar texto, enteros, dni's y fechas Ascendente y Decendente.

Si usan esta clase "tal y como está" Respeten la documentacion XML por favor.

El uso de esta clase se resume en esta sentencia:
Código: Text
  1.  
  2.  Listview1.ListViewItemSorter = New Comparador(e.Column,Comparador.metodo.FechaAsc)
  3.  
  4.  

donde:
    e.Column es un entero que representa la columna a ordenar
    metodo.FechaAsc es el tipo de dato y la forma de orden

Por si las moscas, les comento que ese code se pondria en el evento Column_Click.

Código: Text
  1.  
  2.  
  3. ''' &#60;summary&#62;
  4. ''' Ordena los Items de un ListView segun la columna que se le pase y el tipo de dato
  5. ''' &#60;/summary&#62;
  6. ''' &#60;remarks&#62;Coded by Krnl64 '08&#60;/remarks&#62;
  7.  Public Class Comparador
  8.  
  9.     Implements System.Collections.IComparer
  10.  
  11. ''' &#60;summary&#62;
  12. ''' Tipo de Dato y Orden
  13. ''' &#60;/summary&#62;
  14.     Public Enum metodo
  15.     ''' &#60;summary&#62;
  16.     ''' Texto en orden Ascendente
  17.     ''' &#60;/summary&#62;
  18.     TextoAsc
  19.     ''' &#60;summary&#62;
  20.     ''' Texto en orden Descendente
  21.     ''' &#60;/summary&#62;
  22.     TextoDesc
  23.     ''' &#60;summary&#62;
  24.     ''' DNI's sin tener en cuenta la letra Ascencente
  25.     ''' &#60;/summary&#62;
  26.     DNIAsc
  27.     ''' &#60;summary&#62;
  28.     ''' DNI's sin tener en cuenta la letra Descendente
  29.     ''' &#60;/summary&#62;
  30.     DNIDesc
  31.     ''' &#60;summary&#62;
  32.     ''' Fechas en orden Ascendente
  33.     ''' &#60;/summary&#62;
  34.     FechaAsc
  35.     ''' &#60;summary&#62;
  36.     ''' Fechas en orden Descendente
  37.     ''' &#60;/summary&#62;
  38.     FechaDesc
  39.     ''' &#60;summary&#62;
  40.     ''' Numeros en orden Ascendente
  41.     ''' &#60;/summary&#62;
  42.     ''' &#60;remarks&#62;&#60;/remarks&#62;
  43.     NumeroAsc
  44.     ''' &#60;summary&#62;
  45.     ''' Numeros en orden Descendente
  46.     ''' &#60;/summary&#62;
  47.     NumeroDesc
  48.  
  49.     End Enum
  50.  
  51.  
  52.     Private ordenar As metodo
  53.     Private col As Integer
  54.  
  55.         ''' &#60;summary&#62;
  56.         ''' Constructor
  57.         ''' &#60;/summary&#62;
  58.         ''' &#60;param name=&#34;columna&#34;&#62;Entero que especifica la columna del Listview a ordenar&#60;/param&#62;
  59.         ''' &#60;param name=&#34;datasort&#34;&#62;Tipo de dato a ordenar y la forma&#60;/param&#62;
  60.         Public Sub New(ByVal columna As Integer, ByVal datasort As metodo)
  61.         ordenar = datasort
  62.         col = columna
  63.         End Sub
  64.  
  65.         ''' &#60;summary&#62;
  66.         ''' Comparador de varios tipos de datos
  67.         ''' &#60;/summary&#62;
  68.         ''' &#60;param name=&#34;x&#34;&#62;Cualquier tipo de dato Soportado (Object)&#60;/param&#62;
  69.         ''' &#60;param name=&#34;y&#34;&#62;Cualquier tipo de dato Soportado (Object)&#60;/param&#62;
  70.         ''' &#60;returns&#62;Resultado de la comparacion&#60;/returns&#62;
  71.         Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
  72.  
  73.                Select Case ordenar
  74.  
  75.                             Case metodo.TextoAsc
  76.  
  77.                                             Return (String.Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text))
  78.                             Case metodo.TextoDesc
  79.                                             Return (String.Compare(CType(y, ListViewItem).SubItems(col).Text, CType(x, ListViewItem).SubItems(col).Text))
  80.  
  81.                             Case metodo.DNIAsc ' Puede parecer complicao pero lo que hace es coger el nº del dni sin letra y lo compara
  82.                                             Return (CType(x, ListViewItem).SubItems(col).Text.Substring(0, CType(CType(x, ListViewItem).SubItems(col).Text.Length - 1, Integer)) - CType(y, ListViewItem).SubItems(col).Text.Substring(0, CType(CType(y, ListViewItem).SubItems(col).Text.Length - 1, Integer)))
  83.  
  84.                             Case metodo.DNIDesc
  85.                                             Return (CType(y, ListViewItem).SubItems(col).Text.Substring(0, CType(CType(y, ListViewItem).SubItems(col).Text.Length - 1, Integer)) - CType(x, ListViewItem).SubItems(col).Text.Substring(0, CType(CType(x, ListViewItem).SubItems(col).Text.Length - 1, Integer)))
  86.  
  87.                             Case metodo.NumeroAsc
  88.                                             Return (CInt(CType(x, ListViewItem).SubItems(col).Text) - CInt(CType(y, ListViewItem).SubItems(col).Text))
  89.  
  90.                             Case metodo.NumeroDesc
  91.                                             Return (CInt(CType(y, ListViewItem).SubItems(col).Text) - CInt(CType(x, ListViewItem).SubItems(col).Text))
  92.  
  93.                             Case metodo.FechaAsc
  94.                                             Return (DateTime.Compare(DateTime.Parse(CDate(CType(x, ListViewItem).SubItems(col).Text)), DateTime.Parse(CDate(CType(y, ListViewItem).SubItems(col).Text))))
  95.  
  96.                             Case metodo.FechaDesc
  97.                                             Return (DateTime.Compare(DateTime.Parse(CDate(CType(y, ListViewItem).SubItems(col).Text)), DateTime.Parse(CDate(CType(x, ListViewItem).SubItems(col).Text))))
  98.  
  99.                 End Select
  100.  
  101.         End Function
  102.  
  103.         ''' &#60;summary&#62;
  104.         ''' Destructor
  105.         ''' &#60;/summary&#62;
  106.         Protected Overrides Sub Finalize()
  107.             ordenar = 0
  108.             col = 0
  109.             MyBase.Finalize()
  110.         End Sub
  111.  
  112. End Class
  113.  
  114.  

19
C/C++ / Optimizar Busqueda En Memoria
« en: Viernes 28 de Marzo de 2008, 15:03 »
Hola a todos.

Veran, estoy tratando de hacer un cheat para un juego (solo por gusto, apenas juego xD).

Abro el proceso y busco las variables pertinentes.

Pero todos los procesos empiezan en 0x10000 y acaban en 0x7FFE0FF0
(en mi sistema, o por lo menos eso me dice la estructura SYSTEM_INFO) entonces este bucle que es que lee:

Código: Text
  1.  
  2.  
  3.  
  4.        // si es un puntero a SYSTEM_INFO
  5.  
  6.       currentAddress=(DWORD)si.lpMinimumApplicationAddress;
  7.          // Obtengo la direccion donde comienza el proceso
  8.  
  9.      // Estare leyendo hasta llegar al final del espacio de direcciones del proceso
  10.       while (currentAddress &#60; (DWORD)si.lpMaximumApplicationAddress) {
  11.      
  12.             VirtualQueryEx(...)
  13.              ReadProcessMemory(...)
  14.  
  15.      }
  16.  
  17.  
  18.  
  19.  

Pero tarda siglos en recorrer todas las direcciones. Cómo podria hacer para leer solo las direcciones desde donde empieza a donde acaba ?

Es decir, abri el regmon con el WinHex y empieza en 0x10000 y acaba en 5B187FF0
(en mi equipo)

Como puedo averiguar esa direccion ?

Gracias

20
ASM (Ensamblador) / Bootear Desde Cd
« en: Viernes 14 de Diciembre de 2007, 13:22 »
Hola a todos.

Verán estoy tratando de arrancar el ordenador desde una iso.
Use el FASM para generar el bin de arranque y otro bin que seria un interprete de comandos.

Copiandolos a un floppy y a archivos IMG (para el VMWARE) funciona bien.

Pero qué puedo hacer para conseguir arrancar desde una iso ?

Probe a ponerle un autorun, pero no funciona.

Gracias

21
ASM (Ensamblador) / Pequeñas Dudas En Programa Basico
« en: Domingo 25 de Noviembre de 2007, 22:20 »
Hola a todos.

Estoy empezando en esto del masm32 y codeando un simple programa que te escribe una palabra en la consola y espera a que pulses una tecla para terminar,me han surgido algunas dudas que no consigo resolver.

Les pongo mi code y les cuento:

Código: Text
  1.  
  2.  
  3. .386                                            
  4. .model flat, stdcall
  5. option casemap:none
  6.  
  7. include kernel32.inc
  8. include windows.inc
  9.  
  10.  
  11. includelib kernel32.lib
  12.  
  13. .data
  14.  
  15. ;variables necesarias
  16.  
  17. msg  db 'hola',0
  18. buff db ?
  19.  
  20. hout dd ?
  21. hin  dd ?; handles de e/s
  22.  
  23. tit db 'Consola Demo',0
  24.  
  25.  
  26. .code
  27.  
  28. start:
  29.  
  30.   call con
  31.   call pinta
  32.  
  33.   push hin
  34.   call CloseHandle
  35.          &#59; Cierro los handles abiertos
  36.   push hout
  37.   call CloseHandle
  38.  
  39.   call FreeConsole  &#59; Cierro la consola
  40.  
  41.  
  42.  
  43. ; Salgo de forma controlada
  44. push NULL
  45. call ExitProcess
  46.  
  47.  
  48. con proc      
  49. ;call AllocConsole
  50. ; solicito poder crear una consola
  51. ; Esto sobra porque el programa es de consola
  52.  
  53. push STD_OUTPUT_HANDLE
  54. call GetStdHandle; obtendre el handle de la consola
  55. mov  hout,eax   &#59; copio a hout el handle obtenido
  56.  
  57. push STD_INPUT_HANDLE
  58. call GetStdHandle
  59. mov hin,eax  &#59; handle de entrada
  60.  
  61.  
  62. lea eax,tit
  63. push eax
  64. call SetConsoleTitle
  65. ;titulo de la consola
  66.  
  67. ret  
  68. con endp
  69.  
  70.  
  71. pinta proc
  72.  
  73. push NULL; nulo
  74. lea eax,buff; buffer de escritura
  75. push eax; meto el buffer en la pila
  76. push 4;longitud del mensaje
  77. lea eax,msg
  78. push eax; meto la cadena en la pila
  79. push hout;meto en la pila el handle
  80. call WriteConsole
  81. ;llamo a la funcion
  82.  
  83.  
  84. push NULL
  85. push NULL
  86. push NULL; los parametros son nulos porque no voy a
  87. push NULL; almacenar el dato leido, excepto el handle que
  88. push hin  &#59; es necesario
  89. call ReadConsole
  90.  
  91. ret
  92.  
  93. pinta endp
  94.  
  95. end start
  96.  
  97.  
  98.  



Empiezo a ejecutar y obtengo los handles de E/S de la consola.

Me escribe la palabra hola (esto menos mal que lo hace bien) y espera a que pulse enter, pero en este procedimiento el handle de salida desaparece y en LastError pone ERROR_INVALID_ACCESS.

Cuando regresa a la rutina principal al cerrar los handles, me cierra el handle de entrada pero el de salida no, porque no existe.

FreeConsole y ExitProcess funcionan bien.

Pueden decirme el por qué de estos fallos ? porque estoy buscando info y no consigo averiguarlos.

Creo que el handle de salida de la consola desaparece "solo" porque cumple su funcion y no se va a usar más, pero no estoy muy seguro.

Espero que me puedan aclarar esas dudillas.

Gracias

22
VB .NET / Problema Con Un Algoritmo
« en: Miércoles 21 de Noviembre de 2007, 18:19 »
Hola a todos.
Verán estoy intentando hacer un code que me elimine los elementos repetidos de un vector. Pero resulta que el code que he escrito falla a veces.
Le he dado 1000 vueltas y no se porqué falla (en teoria es correcto lo que he escrito)

Podrían ayudarme a resolver el problema ?
Mi code es este:

Código: Text
  1.  
  2.  
  3. Dim v() As Integer
  4.         Dim i As Integer
  5.         Dim j As Integer
  6.         Dim z As Integer
  7.  
  8.         Dim limit As Integer
  9.         Randomize()
  10.  
  11.         Console.WriteLine(Chr(10) & &#34;Introduzca el numero de elementos del vector&#34;)
  12.         limit = Console.ReadLine
  13.  
  14.         ReDim v(limit - 1)
  15.  
  16.         For i = 0 To v.Length - 1
  17.             v(i) = Int(Rnd() * 10) + 1 'Console.ReadLine
  18.         Next
  19.  
  20.  
  21.           Console.Write(Chr(10) & &#34;El contenido del vector es: &#34;)
  22.  
  23.         For i = 0 To v.Length - 1
  24.             Console.Write(&#34; &#34; & v(i))
  25.         Next
  26.  
  27.             For i = 0 To UBound(v)
  28.  
  29.  
  30.                     For j = i + 1 To UBound(v) - 1 '' me adelanto una pos
  31.  
  32.                         If v(j) = v(i) Then '' Si son iguales...
  33.  
  34.                             For z = j To UBound(v) - 1        '' me pongo en la pos del elemento a borrar
  35.                             If (z &#60;&#62; UBound(v)) Then v(z) = v(z + 1) '' adelanto los elementos 1 lugar
  36.                             Next
  37.  
  38.                             ReDim Preserve v(UBound(v) - 1)
  39.  
  40.                         End If
  41.  
  42.  
  43.                     Next
  44.  
  45.             Next
  46.  
  47.         Console.Write(Chr(10) & &#34;El contenido del vector es: &#34;)
  48.  
  49.         For i = 0 To UBound(v)
  50.             Console.Write(&#34; &#34; & v(i))
  51.         Next
  52.  
  53. Console.ReadKey()
  54.  
  55.  
  56.  

Gracias

23
C/C++ / Limite De Vectores Dinamicos
« en: Lunes 22 de Enero de 2007, 20:37 »
Hola a todos.

Verán, cuando se migra de un lenguaje como VB a C uno hecha de menos ciertas funciones como Lbound y Ubound que devuelven el elemento inferior y superior del vector.

Me pregunto que cómo puedo hacer una función que haga esto.

De esa forma, trabajar con vectores dinámicos seria más cómodo porque podria
disponer de su longitud en cualquier momento y hacer un realloc.

Por ahora lo que hago, es "llevar la cuenta" de los elementos que introduzco en él
en una variable global y tener cuidado de que no se pase.

O en algunos casos,  almaceno Sizeof vector /Sizeof(tipo de dato) en una variable
y lo redimensiono a ese dato.

Puede decirme alguien cómo puedo implementar esta función u otra forma de hacerlo ?

Gracias

24
C/C++ / Duda Con Bin2h
« en: Sábado 2 de Diciembre de 2006, 17:21 »
Hola a todos.

Verán, me baje de programmers Heaven una utilidad para C que transforma 1 fichero PE en uno H.

Mi duda es que no se como usarlo. El programa te genera 1 H con 1 matriz de codigo en ASM.

Yo pensaba que para usarlo, habia que copiar la matriz de codigo a un fichero. Pero no funciona.

Les mando 1 RAR con el programa, un fichero de C y el mismo convertido en H
a ver si alguien sabe usarlo.

Alguien puede ayudarme ?

Gracias

25
C/C++ / Duda Acerca De Los Ficheros De Recursos
« en: Sábado 11 de Noviembre de 2006, 12:37 »
Hola a todos.

Verán, tengo una duda acerca de los ficheros de recursos en C.

Resulta que estoy migrando de VB a C y en VB se podía incluir cualquier fichero
dentro del fichero de recursos. Es decir, en VB yo podia meter 1 OCX que sólo era extraido del fichero de recursos cuando lo necesitaba .

Mi problema actual es el siguiente:

He desarrollado un pequeño compilador (nada serio, ejercicios de clase) y me gustaria incluir si es posible los archivos NASM y TLINK dentro de un fichero de recursos asociado al compilador. De esta forma, solo tendria que portar el compilador estando dentro de él el ensamblador y el linkador.

Tambien existen la posibilidades de guardar los binarios como texto y después volcarlos a un archivo, pero me parece un poco cutre la solución o ejecutar un compresor PE que te integre todos los ficheros PE en uno solo.

Es posible incluir los ficheros PE en uno de recursos asociado al compilador sin usar ninguna de las soluciones anteriores ?

Gracias

Páginas: [1] 2