|
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.
Mensajes - Ruben3d
Páginas: 1 ... 27 28 [29] 30
701
« en: Sábado 31 de Enero de 2004, 22:27 »
Hola. Prueba este código, que abre un archivo para escritura y lo crea si no existe: #include <fstream> using namespace std; int main() { ofstream out("texto.txt"); // Abre para escritura out << "Texto de prueba" << "\n"; // Escribe la cadena en el archivo return 0; }
Espero que te sirva. Un saludo. Ruben3d
702
« en: Lunes 26 de Enero de 2004, 22:23 »
Hola.
Puedes declarar métodos virtuales como inline ya que inline es una sugerencia para el compilador, es decir, no está obligado a hacer caso a la orden.
Por ejemplo, si en algún momento usas la dirección de memoria de la función el compilador no la tratará como inline. O bien, si el compilador detecta que el código de la función inline es considerablemente mayor que el que sería utilizado para realizar una auténtica llamada a una función también sería ignorada la declaración inline (esto depende de cómo se haya configurado la optimización del compilador).
Por esto, cuando declaras un método virtual como inline el compilador simplemente ignora la palabra inline.
Espero que esto te haya aclarado el comportamiento de tu compilador.
Un saludo.
Ruben3d
703
« en: Domingo 25 de Enero de 2004, 21:21 »
Hola. Cómo proyectar coordenadas 3d a la pantalla, de manera muy simple, viene explicado aqui: Perspective view is composed of two things: converting 3D coordinates into 2D coordinates (screen), and making the perspective view. To convert 3D to 2D, there is a simple equation:
X = x / z Y = y / z
Where X, Y are your coordinates on the screen, and x,y,z is a 3D point.
The next part, making the perspective view. To explain this concept, look into a shiny door knob. See how your nose is 2x bigger than normal, and the rest of your face is smaller than normal. This is the fish eye concept. Having a fish eye view, is like an exaggerated perspective view. That is, things that are closer become bigger, and things that are farther become smaller. This concept is used to make 3D games look 3D and not flat. Although your screen is flat, perspective view creates a depth into your screen. To do this, you multiply the x and y by the width of your screen in pixels. That is if you are using 320x200 resolution, you would multiply it by 320, so your formula becomes:
X = 320 * x / z Y = 320 * y / z
The reason why I choose the screen width is because it has to do with how far your face is from the screen. Have you ever tried while playing a 3D game to brind your head really close to the screen and really far from the screen? What you will notice is that the game does not look real anymore. It either looks fish eye (too close) or flat (too far). Using the screen width is a good ratio. That means your head is about a foot away from the screen, which is reasonably good.
Espero que te sirva. Un saludo, Ruben3d
704
« en: Jueves 22 de Enero de 2004, 18:37 »
Acabo de hacer un programa como te he dicho y funciona muy bien. Mira: // // main.cpp // #using <mscorlib.dll> using namespace System; // String, Console void main() { String __gc* cadena("Cadena de caracteres"); for (unsigned int i=0; i<cadena->Length; i++) Console::WriteLine(cadena->get_Chars(i)); Console::ReadLine(); }
El resultado por pantalla es la cadena de texto escrita en vertical. Un saludo. Ruben3d
705
« en: Jueves 22 de Enero de 2004, 14:56 »
Bueno, parece que sí es un poco diferente He buscado en la referencia de microsoft y he encontrado esta propiedad de System::String. [C++] [Serializable] public: __property __wchar_t get_Chars( int index );
Espero que esta te sirva. Un saludo. Ruben3d
707
« en: Jueves 22 de Enero de 2004, 11:25 »
Hola. Si tienes una cadena del tipo std::string y quieres recorrerla caracter a caracter como si se tratara de un vector de tipo char has de usar el método c_str(). Este método devuelve un puntero al buffer en donde se guarda la cadena, por lo que te puedes referir a una posición en concreto usando []. Respecto al uso de connect, has de hacerlo así: connect(g_Socket, (struct sockaddr *) &g_DirRemota, sizeof(g_DirRemota))
De esta manera te funcionará perfectamente. Espero que te haya servido de ayuda. Un saludo. Ruben3d
708
« en: Martes 20 de Enero de 2004, 19:19 »
Si dices que vector es una variable global no hace falta pasarla como parámetro. La función podría ser así: void ReservarMemoriaGlobal(int n1, int n2) { vector = (char*) malloc(n1*n2*sizeof(char)); }
En caso de que no quisieras la variable global, sino local, habrías de hacerlo así: void ReservarMemoriaLocal(char **vector, int n1, int n2) { *vector = (char*) malloc(n1*n2*sizeof(char)); }
y se llamaría a la función así: ReservarMemoriaLocal(&vector, n1, n2);
Espero que te sirva. Un saludo. Ruben3d
709
« en: Martes 20 de Enero de 2004, 19:12 »
Hola.
Tengo un fichero fuente en el que lo único que guardo es la fecha y la hora de la compilación usando __DATE__ y __TIME__. Como cada vez que compilo el proyecto no modifico este fichero, permanece sin recompilar, por lo que cada vez que se genera la aplicación aparece la fecha y hora de la primera vez que lo compilé. ¿Hay alguna manera de forzar la compilación de este fichero sin tener que borrar el código objeto manualmente antes?
Muchas gracias.
Ruben3d
710
« en: Martes 20 de Enero de 2004, 18:43 »
Hola Para reservar memoria para una matriz y asignarla a una variable de tipo char* (en vez de char** que sería lo de esperar) has de hacerlo así: vector = (char*) malloc(n1*n2*sizeof(char));
Una vez reservada la memoria, el acceso a una posición x,y de la matriz sería: Funcionará siempre y cuando n1 sea la anchura, n2 la altura, x se refiera a posición horizontal e y a la posición vertical. El rango para x será [0,n1-1] y el rango de y [0,n2-1]. Espero que te sirva de ayuda. Un saludo. Ruben3d
711
« en: Jueves 15 de Enero de 2004, 22:06 »
No hacía falta que me abrumaras con citas de diversos autores. Con exponerme un argumento bastaba. Respecto a la primera cita, la variación que propone es peligrosa por dos motivos: si no se es cuidadoso con la elección de m (siendo b impar) tendremos un generador que alternará entre números pares e impares. Es más, dependiendo de la elección de b podemos dar lugar a que ciertas semillas generen secuencias de números de periodo 1 . Un ejemplo de esto sería: - Xi+1 = [16807·Xi + 1] mod (2^31-1)</li>
- [16807·1319592028 + 1] mod (2^31-1) = 1319592028</li>
Así, la calidad de un generador congruente lineal está directamente ligada a la elección de las constantes utilizadas, además de la variación elegida. De todas formas, no te puedo quitar la razón cuando dices que los valores pueden predecirse. Es fácil ver que, sabiendo las constantes que se emplean para generar una nueva semilla a partir de la anterior, se puede averiguar qué número será el próximo en generarse a partir del ya dado, como con todo sistema basado en la aplicación de reglas. Es más, si se toma el ejemplo de generador congruente lineal que he dado (basado en la congruencia Xi+1 = aXi mod m) y se multiplica un número generado por éste por m obtendremos la semilla utilizada, por lo que ya sólo restaría inicializar el generador con esta semilla para poder obtener la misma serie de números aleatorios. Ahora bien, cuando menciono "sistema seguro" no me refiero exactamente a la criptografía, sino más bien al grupo más general de sistemas englobados por este término. Por ejemplo, sistemas críticos con algoritmos probabilísticos pueden, perfectamente, utilizar un buen generador congruente lineal (quiero hacer destacar el calificador buen). Para los sistemas criptográficos sería una brecha de seguridad el permitir que se pudieran predecir los números utilizados en la codificación. Es por ello que se utiliza el sistema critográfico RSA (cuya explicación creo que ya sería demasiado off-topic, teniendo en cuenta el tema original del post). Llegado a este punto creo que puedo decir que estoy de acuerdo con QliX=D! en que un generador congruente lineal no sirve para la criptografía, aunque no debe despreciarse su uso para el resto de aplicaciones. Un saludo. Ruben3d
712
« en: Jueves 15 de Enero de 2004, 18:16 »
Las funciones aleatorias no son aleatorias realmente. Hacen unas cuentas y obtienen un valor pseudo-aleatorio. En cada ejecución del programa, las cuentas son las mismas y obtienes los mismos numeros aleatorios. Esto en realidad no es verdad...
Hola a todos. Quería decir que chuidiang sí tiene razón (aunque es algo incompleto). Efectivamente, como bien dice QliX=D!, la función de generación de números aleatorios en C (y en muchos otros lenguajes) implementa un generador congruente lineal. A grandes rasgos, un generador de estas características toma un número, llamado semilla, y le aplica una transformación (no la voy a explicitar aqui). Este nuevo número así generado pasa a ser la nueva semilla, sustituyendo al anterior. A continuación, este número es dividido entre cierto número (llamemoslo m) (de ninguna manera elegido al azar), con lo que se obtiene un nuevo número en el rango [0.0,1.0), que será el retorno de la función. Es cierto que, como señaló QliX=D!, la serie de números generada comenzará a repetirse tras cierta cantidad de pasos. Si el valor de m está bien elegido (además de otros usados en la transformación) conseguiremos un generador de período completo (de tamaño m-1). Para garantizar esto, m ha de ser un primo. Ahora bien, para maximizar el tamaño del periodo, hemos de elegir un m grande, que en máquinas de 32 bits puede ser 2^31-1. Así pues, siempre que se inicie el programa y se empiecen a generar números aleatorios se generará la misma secuencia (como dijo chuidiang) ya que la generación es llevada a cabo por la aplicación consecutiva de una serie de operaciones constantes (con constantes quiero decir que siempre son las mismas y no dependen de ningún factor externo). Sin embargo, si nos fijamos bien en el proceso que he descrito más arriba, la generación se basa en ir aplicando transformaciones a un valor llamado semilla. Dando un valor inicial diferente en cada ejecución (usando la hora, por ejemplo) a la semilla conseguiremos series de números diferentes cada vez que ejecutemos el programa. Estos valores aleatorios no son adecuados para cosas sobre seguridad, pero si para aleatorizar metodos o datos en juegos, etc.
Francamente, opino que los valores así generados sí son aptos para aplicaciones seguras. No hay más que fijarse en el tamaño del periodo: m-1 = (2^32-1)-1 = 2147483646. Lo que más puede poner en compromiso la fiabilidad de un sistema basado en un generador de este tipo es la correcta elección de ciertas constantes que se utilizan (una de ellas es m). Una elección al azar o no estudiada detenidamente puede dar lugar a generadores que altenernen entre números pares o impares, que tiendan a generar más veces ciertos números o que se reduzca su periodo drásticamente, propiedades difícilmente deseables. Bueno, espero haber dejado claro con esta explicación cómo se generan los números aleatorios en los ordenadores. Espero que le sea de ayuda a alguien. Un saludo. Ruben3d
713
« en: Miércoles 31 de Diciembre de 2003, 20:16 »
Hola. Para poder imprimir texto en colores en una terminal has de usar las funciones de la librería ncurses, declaradas en el fichero ncurses.h. En NCURSES Programming HOWTO puedes encontrar un manual sencillo sobre el uso de la librería. Un saludo.
714
« en: Domingo 21 de Diciembre de 2003, 22:32 »
Hola.
Gracias por la respuesta. Sé hacer un triángulo texturizado en OpenGL y en Direct3D, sin embargo mi objetivo es aprender cómo se hace sin usar estas APIs, es decir, cómo funcionan por dentro. Me he comprado hace poco un libro donde viene bastante bien explicado todo lo que es gráficos 3d por software, por lo que ya sólo me resta empollarmelo.
Un saludo.
715
« en: Domingo 21 de Diciembre de 2003, 12:44 »
Hola. Para evitar ese problema debes hacer algo así: #ifndef CLASEA_H #define CLASEA_H class ClaseB; class ClaseC; class ClaseA { public: void metodo(ClaseB *B, ClaseC *C); }; #endif // CLASEA_H
Un saludo.
716
« en: Miércoles 17 de Diciembre de 2003, 14:22 »
La función que buscas es sprintf.
Un saludo.
717
« en: Martes 16 de Diciembre de 2003, 16:57 »
Esta es una versión resumida de la clase (le he quitado variables privadas y temas varios que no influyen para que aparezca el warning), que aparece en el fichero de cabecera que emite el warning. class Screen { static Screen m_Screen; std::string m_title; bool m_used; Screen(std::string title) : m_title(title), m_used(false) {}; Screen(const Screen&) {}; public: ~Screen(); int Init(); void Print(textattr_t type, const char *text, ...); void Read(char *text, int maxsixe); void Done(); static Screen* Handler() {return &m_Screen;} };
Aunque el constructor sea privado, en el fichero .cpp sí se llama al constructor al iniciar la variable estática m_Screen: Screen Screen::m_Screen("Cliente IRC");
Para acceder a los métodos de la clase, la única manera es escribirlo de esta forma: Screen::Handler()->Print( lo que sea );
Con esta definición la aplicación compila y funciona perfectamente, a pesar del aviso informandome de un posible error que no es tal. Además, se protege la clase para que no se puedan crear más instancias de ella. Un saludo.
718
« en: Lunes 15 de Diciembre de 2003, 15:10 »
Hola. Gracias por responder.
El compilador lo tengo configurado para que compile según el estándar ANSI C++ con las extensiones GNU, por lo que no tiene nada raro.
Soy perfectamente consciente de que los warnings muchas veces ayudan a encontrar errores (siempre compilo con -Wall, para que muestre todos los warnings), pero en este caso concreto el que no haya ningún constructor público es debido a que no quiero que el usuario haga más instancias de la clase además de la que ya hay (como ya dije, sigue el patrón de diseño singleton, en el cual sólo hay una instancia estática privada de la propia clase y se accede a ella a través de un método estático que devuelve un handler).
Por otro lado, tras consultar toda la documentación del compilador gcc me di cuenta de que no se puede quitar un warning concreto, sino los de algún tipo, o alguno que tenga definido un parámetro concreto, o todos. No hay un código asociado a cada tipo de warning como en otros compiladores, para poder tratarlos individualmente.
Un saludo.
719
« en: Domingo 7 de Diciembre de 2003, 23:22 »
Hola.
Bajo linux, para poder cambiar el color del texto, la posición, etc. has de usar la librería ncurses (pon un include a ncurses.h y compila con -lncurses). Ahora no tengo a mano ningún link a tutoriales de la librería, pero no es difícil encontrarlos en google. Con respecto a trabajar más cómodamente, yo uso kdevelop 3, que es un entorno de desarrollo estilo visual studio.
Un saludo.
720
« en: Lunes 1 de Diciembre de 2003, 20:02 »
Hola a todos. He hecho una clase de tipo singleton y, al compilar el archivo, obtengo el siguiente warning: cscreen.h:26: aviso: `class Screen' solamente define constructores privados y no tiene friends
Con Visual Studio puedo quitar los warnings con la directiva #pragma warning( disable : X ) pero, ¿cómo puedo hacerlo coon g++? Muchas gracias
721
« en: Domingo 30 de Noviembre de 2003, 17:04 »
Hola de nuevo.
Ya encontré la solución a mis problemas: La librería ncurses.
Un saludo.
722
« en: Sábado 29 de Noviembre de 2003, 13:38 »
Hola a todos.
Tengo un programa que representa objetos formados por triángulos, pero son de colores sólidos cuya intensidad varía según la posición de la luz. Lo que hago para pintarlos es proyectar las coordenadas xyz de los vértices a coordenadas xy de la pantalla y rellenar el triángulo 2d resultante con el tono adecuado. Desde esta situación, ¿cómo podría texturizar los triángulos? No quiero el código, sino más el concepto, qué es lo que hay que hacer. Me gustaría que alguien me explicara el método o me diera un link a donde estuviera explicado de manera más o menos clara, de manera genérica (sin centrarse en un lenguaje de programación en particular).
Muchas gracias a todos.
723
« en: Viernes 28 de Noviembre de 2003, 22:27 »
Hola. Hay un programa, llamado miniterm, que sirve para enviar caracteres por el puerto serie. El código que te paso está configurado para el COM2 (ttyS1) me parece recordar, ya que el COM1 es ttyS0, pero esto último no lo recuerdo con seguridad. No te debe ser difícil modificarlo para que envie un archivo en vez de lo que teclee el usuario. /* * AUTHOR: Sven Goldt (goldt@math.tu-berlin.de) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ /* This is like all programs in the Linux Programmer's Guide meant as a simple practical demonstration. It can be used as a base for a real terminal program. */ #include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #define BAUDRATE B38400 #define MODEMDEVICE "/dev/ttyS1" #define ENDMINITERM 2 /* ctrl-b to quit miniterm */ #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; void child_handler(int s) { STOP=TRUE; } main() { int fd,c; struct termios oldtio,newtio,oldstdtio,newstdtio; struct sigaction sa; /* Open modem device for reading and writing and not as controlling tty because we don't want to get killed if linenoise sends CTRL-C. */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* save current modem settings */ /* Set bps rate and hardware flow control and 8n1 (8bit,no parity,1 stopbit). Also don't hangup automatically and ignore modem status. Finally enable receiving characters. */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* Ignore bytes with parity errors and make terminal raw and dumb. */ newtio.c_iflag = IGNPAR; /* Raw output. */ newtio.c_oflag = 0; /* Don't echo characters because if you connect to a host it or your modem will echo characters for you. Don't generate signals. */ newtio.c_lflag = 0; /* blocking read until 1 char arrives */ newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; /* now clean the modem line and activate the settings for modem */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* Strange, but if you uncomment this command miniterm will not work even if you stop canonical mode for stdout. This is a linux bug. */ tcsetattr(1,TCSANOW,&newtio); /* stdout settings like modem settings */ /* next stop echo and buffering for stdin */ tcgetattr(0,&oldstdtio); tcgetattr(0,&newstdtio); /* get working stdtio */ newstdtio.c_lflag &= ~(ICANON | ECHO); tcsetattr(0,TCSANOW,&newstdtio); /* terminal settings done, now handle in/ouput */ switch (fork()) { case 0: /* child */ /* user input */ close(1); /* stdout not needed */ for (c=getchar(); c!= ENDMINITERM ; c=getchar()) write(fd,&c,1); tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */ tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */ close(fd); exit(0); /* will send a SIGCHLD to the parent */ break; case -1: perror("fork"); tcsetattr(fd,TCSANOW,&oldtio); close(fd); exit(-1); default: /* parent */ close(0); /* stdin not needed */ sa.sa_handler = child_handler; sa.sa_flags = 0; sigaction(SIGCHLD,&sa,NULL); /* handle dying child */ while (STOP==FALSE) /* modem input handler */ { read(fd,&c,1); /* modem */ write(1,&c,1); /* stdout */ } wait(NULL); /* wait for child to die or it will become a zombie */ break; } }
724
« en: Viernes 28 de Noviembre de 2003, 16:57 »
Hola a todos. La función scanf retorna el número de valores leidos con éxito, por lo que basta comprobar este valor (debe ser 1 en este caso) para saber si el usuario ha introducido un entero. Un ejemplo de aplicación de esto sería: #include <stdio.h> void main() { int num; int res; printf("Escribe un numero:n"); fflush(stdin); res = scanf("%d", &num); while (res == 0) { printf("Por favor, introduzca un numero valido.n"); fflush(stdin); res = scanf("%d", &num); } printf("El numero es: %dn", num); }
Espero que esto te sirva de ayuda. Un saludo.
725
« en: Viernes 28 de Noviembre de 2003, 16:42 »
Hola.
En C++ sí hay booleanos: el tipo bool cuyos valores posibles son true y false. Si programas usando VisualC, microsoft tiene definido el tipo BOOL para C (igual que tambien tiene WORD y DWORD, por ejemplo).
Un saludo.
Páginas: 1 ... 27 28 [29] 30
|
|
|