Páginas: Anterior 1 2 3 4 5 6 7 8 ...13 14 15 Siguiente

Do you want to meet me?

16 02 2009
VN:F [1.7.4_987]
Rating: 7.5/10 (2 votes cast)
VN:F [1.7.4_987]
Rating: 0 (from 0 votes)
Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • Meneame
  • PDF
  • RSS
  • StumbleUpon
  • Technorati


Instalar Jflex y Cup en Ubuntu

14 02 2009

Para la instalación es necesario tener habilitados los repositorios Universe. Podemos buscar los paquetes necesarios en Synaptic llamados jflex y cup o bien ejecutamos en consola:

1
$ sudo apt-get install jflex cup

Para que las bibliotecas esten disponibles al realizar nuestros programas, debemos agregarlas al classpath del sistema. JFlex y Cup se encuentran en:

?Descargar path.txt
1
/usr/share/java

Por lo tanto, para incluir dichas bibliotecas en el classpath:

1
$ export CLASSPATH=$CLASSPATH:/usr/share/java/cup.jar:/usr/share/java/JFlex.jar

Si queremos que se ejecute en cada sesión y no tener que volver a hacerlo cada vez que iniciamos sesión siendo un cambio permanente, lo incluimos en el bashrc (ejecutandolo una sola vez y en una línea):

1
echo "export CLASSPATH=$CLASSPATH:/usr/share/java/cup.jar:/usr/share/java/JFlex.jar" | tee -a ~/.bashrc
VN:F [1.7.4_987]
Rating: 0.0/10 (0 votes cast)
VN:F [1.7.4_987]
Rating: 0 (from 0 votes)
Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • Meneame
  • PDF
  • RSS
  • StumbleUpon
  • Technorati


Menús y cambio de formas geométricas con OpenGL

12 02 2009

OpenGL es un librería de gráficos bastante versátil. En este artículo vamos a ver un pequeño ejemplo de su potencial.

El ejemplo consiste en dibujar un triángulo blanco en una ventana y que al pulsar la tecla ‘c’ nuestro triángulo se coloree de rojo, verde y blanco en cada vértice. Por otro lado si pulsamos la tecla escape ‘Esc’ la aplicación terminará. Además añadiremos un pequeño menú que se accionara al pulsar el botón derecho del ratón, donde tendremos la opción de cambiar de modo y salir.

Una pequeña imagen que detalla el proceso:

opengl-triangulos-ejemplo

Ejemplo sencillo con OpenGL

A continuación pongo el código y más adelante lo detallo paso a paso:

?Descargar ejercicio.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include < stdio.h >;
#include < stdlib.h >;
#include < GL/glut.h >;
 
enum {
  MENU_CHANGE = 1,
  MENU_EXIT
};
 
static int mode = 0;
 
void SelectFromMenu(int idCommand)
{  
    switch (idCommand)
    {
        case MENU_CHANGE:
            mode = (mode == 0) ? 1: 0;
            glutPostRedisplay();
            break;
 
        case MENU_EXIT:
            exit(0);
            break;
    }
    glutPostRedisplay();
}
 
void Keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27: // ESCAPE key
            exit(0);
            break;
 
        case 'c':
            SelectFromMenu(MENU_CHANGE);
            break;
    }
}
 
int buildPopupMenu(void)
{
    int menu = glutCreateMenu(SelectFromMenu);
    glutAddMenuEntry("Cambiar modo\tc", MENU_CHANGE);
    glutAddMenuEntry("Salir\tEsc", MENU_EXIT);
 
    return menu;
}
 
void display ()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -4.0); 
 
    if(mode == 0)
    {
        glBegin(GL_TRIANGLES);
 
            glColor3f (1.f, 1.f, 1.f);    // White colour
            glVertex3f(0.0, 1.0, 0.0);
            glVertex3f(-1.0, -1.0, 0.0);
            glVertex3f(1.0, -1.0, 0.0);
 
        glEnd();
    }
    else
    {
        glBegin(GL_TRIANGLES);
 
            glColor3f (0.f, 1.f, 0.f);    // Green colour
            glVertex3f(0.0, 1.0, 0.0);
 
            glColor3f (1.f, 1.f, 1.f);    // White colour
            glVertex3f(-1.0, -1.0, 0.0);
 
            glColor3f (1.f, 0.f, 0.f);    // Red colour
            glVertex3f(1.0, -1.0, 0.0);
 
        glEnd();
    }
 
    glutSwapBuffers();
}
 
void resize (int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50., w/(double)h, 1., 10.);
    glMatrixMode(GL_MODELVIEW);
}
 
void init (void)
{
    glEnable(GL_DEPTH_TEST);
}
 
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(400, 400);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Ejercicio");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
    glutKeyboardFunc(Keyboard);
 
    buildPopupMenu();
    glutAttachMenu(GLUT_RIGHT_BUTTON);
 
    glutMainLoop();
 
    return 0;
}

El funcionamiento principal, es tener una función display(), que según en el modo que estemos, dibujara una u otra figura (coloreada de una manera u otra). Para ello utilizaremos una variable global estática con la que guardaremos el modo en el que estamos, cuando se requiera redibujar, miraremos el modo y lo cambiaremos y dibujaremos la nueva figura. Las funcion de keyboard() llamará al menu según la tecla (salir o cambiar modo) y el menú se encargara de llamar a display y cambiar el modo.

De forma más detalla en la funcion main() primero pasamos los argumentos de entrada con glutInit() y inicializamos glutInitDisplaymode con un doble buffer y RGB, ya que necesitaremos un buffer doble para que nuestras figuras se rendericen en un frame y mientras en otro se procesen.

Le damos un tamaño a la ventana de 400×400 con glutInitWindowSize() y en la posición 200×200 con un título de ventana “Ejercicio”. y llamamos a la función init para que active la prueba de profundidad.

Luego asignamos una funcion de retrollamada (callback) para mostrar nuestra ventana con lgutDiplayFunc(), la función de retrollamada sera display(), que la veremos más adelante.

Otra función de retrollamada para cuando redimensionemos la ventana y despues llamaremos a buildPopupMenu() que sera una función para construir nuestro menú.

Y adjuntaremos el menú cuando se presione el botón derecho del ratón con glutAttachmenu(). Despues llamamos al bucle principal de glut.

Nota: algo importante a resaltar, si utilizas una tarjeta gráfica ATI, es posible que tengas algun fallo si pones la línea, ya que el buffer no quedara totalmente limpio al dibujar en pantalla:

1
 glClear(GL_COLOR_BUFFER_BIT);

Por eso es mejor ponerlo así y evitamos este tipo de fallos (desconozco si en otras tarjetas se da dicho fallo):

1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Para compilar:

gcc -lGL -lGLU -lglut ejercicio.c -o ejercicio

Y ejecutarlo:

./ejercicio

¿Te ha gustado o resultado útil? Pues deja un comentario con tu opinión ;)

VN:F [1.7.4_987]
Rating: 4.0/10 (3 votes cast)
VN:F [1.7.4_987]
Rating: 0 (from 0 votes)
Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • Meneame
  • PDF
  • RSS
  • StumbleUpon
  • Technorati


Palíndromo en C desde un fichero

5 02 2009

Introducción

Estos días he tenido que hacer un pequeño ejemplo de un programa en C, aparentemente sencillo, pero del que no he encontrado buenas soluciones en Google, ni siguiera en otros idiomas más dados.

Casi todos los ejemplos que veía por internet eran poco elegantes, no cuidaban el tratamiento de errores y además todos pedían la entrada de datos por línea de órdenes. Asi que me ha parecido útil ponerlo en el blog, para que gente que se encuentre con el problema en un futuro, tenga una buena referencia o al menos aproximada a su solución.

Descripción del problema

El problema consiste en crear un programa en C que pida el nombre de un archivo de texto y devuelva el número y el palíndromo de todos los posibles palíndromos encontrados en dicho archivo.

Un palíndromo segun Wikipedia es:

Una palabra, número o frase que se lee igual hacia adelante que hacia atrás.

Por ejemplo algunas palabras: ala, bob, solos, reconocer, …

Y alguna frases como:

Dabale arroz a la zorra el abad

En nuestro caso por simplicidad y caso común detectaremos solo las palabras y no frases o textos enteros, ya que si no esto podría complicarse hasta un nivel mayor, aunque tampoco sería demasiado complicado.

Resolución del problema

Supongamos que tenemos un fichero de ejemplo con algunos palíndromos como el siguiente:

?Descargar ejemplo.txt
1
2
3
4
5
Este es un archivo de prueba
que contiene palíndromos como
pueden ser: ala anilina reconocer solos otto bob
pero por ejemplo no son palindromos
solas ola

El siguiente programa, detectara los palíndromos según nuestros propósitos (lo explico más detalladamente después):

?Descargar palin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include < stdio.h>;
#include < stdlib.h>;
#include < string.h>;
 
int searchPalin(char *cad)
{
    unsigned int i = 0, d = (int) strlen(cad)-1;
    int palin=1;
    while ((palin == 1) && (i < ((int)strlen(cad))))
    {
        if (cad[i] != cad[d]) palin=0;
        else
        {
            i++;
            d--;
        }
    }
    return palin;
}
 
int main(int argc, char** argv)
{
    if(argc < 2)
    {
        fprintf(stderr,"palin: opción inválida\nEl primer argumento debe ser un nombre de archivo.\n");
        return 1;
    }
 
    char *namefile=argv[1];
    FILE *fd;
 
    if((fd=fopen(namefile,"r")) == NULL)
    {
        fprintf(stderr,"palin: Error al abrir el archivo.\n");
        return 1;
    }
    else
    {
        printf("Buscando palíndromos en archivo: %s\n",namefile);
 
        fseek(fd, 0, SEEK_END);
        long length = ftell(fd);
        fseek(fd, 0, SEEK_SET);
        char *w;
        w = (char *) malloc(length*sizeof(char *));
        int i,j,p=0;
 
        fread(w, sizeof(unsigned int), length, fd);
        fclose(fd);
 
        char *aux;
        aux = (char *) malloc(strlen(w)*sizeof(char *));
        for(i=0,j=0;i<strlen(w);i++)
        {
            if(w[i] == ' ' || w[i]=='\n')
            {
                aux[j] = '\0';
                j=0;
                if(searchPalin(aux)) printf("%d. %s\n",++p,aux);
            }
            else
            {
                if(w[i] != '\t' && w[i] != ' ');
                {
                    aux[j] = w[i];
                    j++;
                }
            }
        }
    }
    return 0;
}

Bien pasemos a la explicación detallada:

Las tres primeras lineas incluyen en las bibliotecas necesarias para el funcionamiento del programa, la de entrada/salida estandar, la biblioteca estandar y la biblioteca de cadenas (útil para estos propósitos).

La función searchPalin es la que puedes encontrar en la mayoría de los sitios de internet, se encarga de contar los caracteres de la cadena e ir viendo desde el principio al final si van coincidiendo por el principio y por el final. Si es así retorna un valor booleano verdadero (líneas 5 a 19).

En la función main primero comprobamos que hemos recibido un número correcto de argumentos, al menos los necesarios, ya que más de los estrictos, serán ignorados (líneas 23 a 27).

Como segunda comprobación tenemos que asegurarnos que el parámetro del nombre de fichero dado, existe y se puede abrir para lectura, si es así ya podemos procesar el archivo en busca de palíndromos (líneas 29 a 36).

Por comodidad para realizar la lectura del archivo utilizamos la función fread() (línea 48), por lo que será necesario saber la longitud del fichero. La longitud de un fichero no es difícil de calcular, pero hay que tener un aspecto en cuenta.

La función que tenemos disponible para el cálculo de la longitud de un fichero es ftell(), pero dicha función retorna el indicador de posición de fichero, que al comenzar la lectura será 0, luego, necesitamos posicionarnos al final del fichero, después llamar a ftell() y por último volver al principio del fichero para empezar a leer caracteres mediante fread(). Para posicionarnos al principio y al final utilizamos fseek() consiguiendo nuestro propósito (lineas 41 a 43) .

Después cerraremos el archivo con fclose() (línea 49), ya que habremos leído todos los caracteres y los habremos almacenado en una variable llamada w, con la peculiaridad, de que se hace una reserva dinámica de memoria con la cantidad exacta de caracteres del archivo, aprovechando que ya habíamos calculado la longitud del archivo (línea 44 y45), por lo que no nos limitamos a una cantidad en un archivo (como hacen otras posibles implementaciones).

También necesitaremos una cadena auxiliar (aux) en la que reservaremos la cantidad de carácteres que tenga w (línea 51 y 52).

Posteriormente procesaremos nuestra cadena y si leemos un carácter normal que no sea un espacio en blanco o un tabulador, lo almacenaremos en nuestra cadena auxiliar (líneas 61 a 68). Si por el contrario encontramos un salto de línea o un espacio en blanco (lineas 55 a 60) , entonces sera una palabra distinta, por lo que procesaremos el contenido que tengamos en aux, ademas de añadir el carácter ‘\0′ de final de cadena (línea 57). Esto último es importante, ya que si no añadimos ese carácter no se interpretara bien la cadena al no estar completa y ser una sucesión de caracteres (peculiaridades de C).

Llamaremos a la función searchPalin para que nos verifique si la cadena aux es un palindromo y si es, mostraremos el número de palindromo y el palíndromo en sí.

Compilación y ejecución

Para compilar el archivo, se puede hacer a pelo, o bien podemos utilizar un makefile (mucho más cómodo) como el siguiente:

?Descargar Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BINARY = palin
CFLAGS = -o
CC = gcc
RM = rm
 
all:
	@echo Compilando...
	$(CC) $(BINARY).c $(CFLAGS) $(BINARY)
	@echo Hecho.
 
clean:
	@echo Limpiando...
	$(RM) -f *.o *~
	@echo Hecho.

Para compilar escribimos:

?Descargar compilar.txt
1
$ make

Para ejecutar el binario con el fichero de ejemplo.txt:

?Descargar ejecutar.txt
1
$ ./palin ejemplo.txt

Y debe dar una salida como:

?Descargar salida.txt
1
2
3
4
5
6
7
Buscando palíndromos en archivo: ejemplo_old.txt
1. ala
2. anilina
3. reconocer
4. solos
5. otto
6. bob

Para limpiar la compilación:

?Descargar limpiar.txt
1
$ make clean

Y eso es todo, no es muy complicado, pero requiere varios detalles en los que se debe prestar atención.

Cualquier sugerencia de mejora o comentario adicional es bienvenido.

Happy coding!

VN:F [1.7.4_987]
Rating: 5.5/10 (2 votes cast)
VN:F [1.7.4_987]
Rating: 0 (from 0 votes)
Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • Meneame
  • PDF
  • RSS
  • StumbleUpon
  • Technorati


Pruebas

11 12 2008

El testing de programas puede convincentemente demostrar la presencia de errores, pero nunca puede demostrar su ausencia.

Edsger W. Dijkstra.
Sobre la crueldad de verdaderamente enseñar ciencias de la computación

VN:F [1.7.4_987]
Rating: 9.0/10 (2 votes cast)
VN:F [1.7.4_987]
Rating: 0 (from 0 votes)
Comparte, descargalo en pdf, imprimelo o enviaselo a un amigo!
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • Meneame
  • PDF
  • RSS
  • StumbleUpon
  • Technorati


Páginas: Anterior 1 2 3 4 5 6 7 8 ...13 14 15 Siguiente