elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


  Mostrar Mensajes
Páginas: 1 ... 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [19] 20 21 22 23 24 25 26
181  Programación / Programación C/C++ / Re: Biblioteca de matriz de cadenas en: 8 Marzo 2014, 18:37 pm
Bueno eferion, aquí la respuesta es cuestión de gustos. Ambas soluciones son funcionales, por supuesto que usando plantillas STL el código es más breve y fácil para el programador, pero por otra parte hay cierta "sobrecarga", al invocar reiterativamente otras clases y sus métodos.

Claro que las clases STL están optimizadas para aumentar la velocidad de ejecución, pero mi intención aquí fue proponer una clase de matrices que usara sólo los más métodos más básicos, y sin invocar a otras clases. Pero al fin ahora tenemos dos enfoques diferentes para el mismo problema ...
182  Programación / Programación C/C++ / Re: Recibir int seguro en: 8 Marzo 2014, 18:19 pm
Claro, el "desbordamiento de buffer" es un problema típico en la programación, y que por supuesto debemos evitar.

Para C (en C++ el tamaño del arreglo se ajusta automáticamente) una solución sería usar fgets(char *s, int size, FILE *stream), que limita la cantidad de caracteres leídos a size - 1 (se resta uno porque la última posición está reservada para el nulo de terminación). En stream hemos de poner stdin para que lea de la entrada estándar (hay unas consideraciones con fgets() que explicaré al final)

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. int getInt(char *);
  7. int isInt(char * s);
  8.  
  9. int main( ) {
  10.  
  11. int x;
  12. char msg[] = "Intro numero: ";
  13.  
  14. printf("Numero es: %d\n", getInt(msg));
  15. }
  16.  
  17. int getInt(char *msg) {
  18.  
  19. #define N 3
  20. char s[N + 1];
  21. int i;
  22. char clean_return;
  23.  
  24. do {
  25. printf("%s", msg);
  26. fgets(s, N + 1, stdin);
  27.  
  28. /* reemplazar '\n' (si se encuentra) por '\0' */
  29. i = -1;
  30. clean_return = 1;
  31. while ( s[++i] != '\0' )
  32. if ( s[i] == '\n' ) {
  33. s[i] = '\0';
  34. clean_return = 0;
  35. break;
  36. }
  37.  
  38. /* si no se pasó '\n' al arreglo, limpiarlo del bufer de entrada */
  39. if ( clean_return ) getchar();
  40. } while( *s == '\0' || !isInt(s) );
  41.  
  42. return atoi(s);
  43. }
  44.  
  45. int isInt(char * s) {
  46.  
  47. int i = -1;
  48.  
  49. while ( s[++i] != '\0' ) {
  50. if( !isdigit(s[i]) )
  51. return 0;
  52. }
  53. return 1;
  54. }

El programa pide al usuario un cadena, que es evaluada como entero siempre y cuando todos sus caracteres sean numéricos. De lo contrario, pide de nuevo. Al final imprime lo que leyó, para verificar.

Como ya se explicó, si por ejemplo declaras un arreglo char[] de N+1 caracteres, entonces fgets() lee como mucho N caractares. Si el fin de línea se encuentra dentro de esos N caracteres (si la cadena tiene una longitud menor N) entonces el fin de linea '\n' es pasado al arreglo. De lo contrario, (si la longitud de la cadena es mayor o igual a N) el '\n' no se pasa al arreglo y queda "pendiente" en el flujo de entrada del teclado. Por eso es necesario eliminarlo con getchar()

Se podría hacer una modificación al isInt() con el objeto de admitir un único carácter de signo '-' al inicio de la cadena, así permitir números negativos.

El código propuesto está en C, lo que implementa una solución más "básica" que C++. Creo que una simple operación de lectura de datos por teclado no exige invocar el complejo modelo de objetos de E/S de C++ ..... (bueno aunque de ahí en adelante no opino más, ello depende del gusto del programador)
183  Programación / Programación C/C++ / Re: tableros en: 8 Marzo 2014, 17:08 pm
Interesante la simplificación de leosansan, ventajas del trabajo en equipo. Te cuento que soy de Guayana, en el sur de Venezuela, y aquí consideramos como prócer a Manuel Carlos Piar, de quién se dice era hijo de Canarios (y Bolívar desarrolló una infame envidia y rivalidad contra él, mandándolo a fusilar). Piar fue un formidable oficial que combió técnicas de estrategia, en oposición a la lucha de burda de carnicería acostumbrada por entonces, y así llegó invicto en el campo de batalla hasta el final de sus días.

Eferion, gracias, realmente había olvidado liberar la memoria (sorry).

Ahora otra vez leo, me parece interesante tu simplificación del código, pero explícamente la aritmética usada de 12, 18, 36, etc ..... No entiendo esas fórmulas, y creo que también hubiera sido bueno comentariar esa explicación en el programa, los demás no somos adivinos jejejeje (broma)
184  Programación / Programación C/C++ / Re: ayuda en: 6 Marzo 2014, 17:13 pm
Amigos, no era mi intención ponerme por encima de otros, pues tampoco quiero que ese rasgo caracterice mi personalidad.

Hace rato comenté que cuando era más joven yo era impulsivo, pero eso fue un error y quiero darlo por superado.

Mi comentario vino al caso pues siendo mi profesión u ocupación, y dada la naturaleza o tipo del problema, quise dar mi aporte en la materia del conocimiento que atañe a este ejercicio. Y siempre ha sido así en post similares que tratan temas matemáticos (operaciones con bases numéricas, resolución de ecuaciones, etc).

En fin, sólo quise hacer unos comentarios para nutrir la "base de información" disponible por todos para la resolución del problema. Y por supuesto que yo NO HARÍA estos comentarios si se tratase de ejercicios o temas de otra naturaleza: trato de limitarme a mi ámbito y no invadir el de los demás. Considero que esa es la base filosófica del respeto ajeno, tan necesario en este mundo.

La otra vez estaba pensando en compartir un código que hice hace tiempo para dibujar por consola (con asteriscos y líneas) la gráfica de una función. En coordenadas polares, y con algunas ecuaciones particulares tomadas de los libros, se producen una gráficas bellísimas (lissajous, mariposas, etc). Me gustaría poder hacerlo sin herir la sensibilidad de nadie aquí en el foro.

¿Saben? Me entristece mucho esa persistente rivalidad entre ingenieros y matemáticos, que se puso de manifiesto en un comentario que me hicieron. Y para ver que las cosas no son siempre lo que paracen, en realidad yo también soy ingeniero, pero estudioso de las matemáticas por afición. En realidad, también me gustan el ajedrez y otras cosas, jeje. Enseño matemáticas como mi trabajo, de eso me gano la vida. Una vez en una conferencia sobre métodos numéricos el ponente (que sí era un Matemático de carrera, al contrario que yo) salió con el bendito tema: los ingenieros esto y aquéllo .... Y yo por supuesto no le respondí, porque ya me tienen cansado con ese asunto .

No se, es una rivalidad que no debería existir. Antes no era así, recordemos que Pascal fue pionero en el diseño de una máquina de calcular, que luego fue perfeccionada por también matemático Leibniz. El Álgebra, la Aritmética y la Lógica siempre han estado ligadas a la Computación, y no se realmente por qué ahora existe ese divorcio y esa competencia. En la antiguedad, muchos intelectuales eran integrales e indagaban en varias áreas. Descartes es conocido por filósofo, pero también como autor del "plano cartesiano". Newton fue conocido por físico, pero sorprendentemente también fue alquimista. Y Leonardo, inventor, ingeniero y artista.

Pero en fin muchachos, reflexionando sobre la realidad actual del mundo está claro que por sobre todas las cosas: Hagamos la Paz y no la Guerra.   :D
185  Programación / Programación C/C++ / Re: encontrar el ultimo valor de la matriz recorrida en: 6 Marzo 2014, 16:38 pm
COOL !!!!!!!!!!!

Mira, tengo que hacerle unos ajustes para correrlo en Linux pues como sabes no sirve windows.h. En particular, cambiar los métodos color() y gotoxy() que controlan aspectos de la terminal, para que funcionen en base a secuencias de escape.

Por cierto una curiosidad, ¿por qué no codificaste esos métodos basados en servicios de BIOS, que es como creo están implementados en conio (hasta donde tengo recuerdo, con los viejos compiladores de Borland 16bits y 32bits que usé alguna vez para Windows)?

Leo, se me ocurre que una forma de ampliar el programa, sería habilitar las teclas de flecha, para uno poder conducir la pelota por en medio de los obstáculos, algo como mini-pinball. Me ofrecería a hacer algo de esa parte, puesto que ya tú ya hiciste lo primero, jeje (complementarnos en vez de competir) ....
186  Programación / Programación C/C++ / Re: [C] Rombo con asteriscos en: 6 Marzo 2014, 16:37 pm
Bueno ..... creo que ya hemos dado una tremenda cantidad de opciones al autor del post sobre cómo resolver su problema.

Lástima que él no haya seguido escribiendo, y al final terminamos agarrándonos el tema para nosotros, jeje  :laugh:

187  Programación / Programación C/C++ / Re: tableros en: 6 Marzo 2014, 15:33 pm
Leo, ya se que él dijo tres fichas, pero no se en qué posición deben ir. Por eso dejé a potestad del autor del post poner las fichas en su lugar  :D

Y leosansan coincido contigo en lo bueno de la sana competencia, sin hacer la violencia.

Y disertando contigo sobre el tema, pienso (no se si discrepo contingo) que no hay que ser tan extremista en el uso de lo básico, ¿no has considerado positivo de uso de macros, constantes y ficheros de cabecera? Hará tu programa más flexible y configurable, además tendrá la fácil posibilidad de ampliarse o modificarse. Los proyectos profesionales hacen uso de este recurso, por ejemplo los nombres que usé los tomé del fichero de cabecera de la biblioteca ncurses, y supongo que lo mismo ocurre con conio.

No me gusta ser "talibán" o extremista [lo fui cuando era más joven, y creo que fue un error  :-(]. Por ejemplo hay programadores de C que son "linuxeros" exclusivos y hacen sus programas dependientes de Linux, discriminando a los usuarios Windows. Otros lo mismo pero al revés. Aunque yo prefiero Linux, trato de hacer mis programas de C de modo que sean compatibles en ambos sistemas, soy consciente de que el 90% o más de los usuarios del mundo usan Microsoft y eso hay que respetarlo.

No los hago compatible también para Apple porque no la conozco, no tengo Mac (es muy caro en mi país, jeje  :laugh:)

Y para cerrar, aunque no es el motivo de este foro, cuento que mi país (Venezuela) está tomado actualmente por la violencia, pido a todos hagan el deseo de que esto cese, y retornen la Justicia y la Libertad a mi tierra. España pasó por Franco, Chile por Pinochet, ... etc, todos los ciudadanos hispanos han padecido el totalitarismo (de derecha o de izquierda, que al fin resulta lo mismo) y deberían poder comprender mis palabras ...
188  Programación / Programación C/C++ / Re: encontrar el ultimo valor de la matriz recorrida en: 5 Marzo 2014, 21:24 pm
Sería muy interesante hacer la animación de la pelota rebotando (refrescamiento de pantalla cuadro a cuadro y con pausa entre ellos), al estilo de un videojuego  :laugh:

¿alguien se atreve?
189  Programación / Programación C/C++ / Re: [C] Rombo con asteriscos en: 5 Marzo 2014, 21:23 pm
Buenos días, lamento llegar un poco tarde, tampoco ser entrometido (como me acusaron en otro post  >:()

Inspirándome un poco en el enfoque de rir7360 que "centró" el rombo, es decir tomó los índices de -N a N, en lugar de 0 a 2*N, quiero aportar una función que dibuja un rombo general con cualquier número de líneas (impar positivo) dado.

El main() pide al usuario la cantidad de líneas del rombo, pero esto esta interfaz se puede modificar. Lo importante es el código de la función rombo() que gracias al enfoque de "centrar" los valores no requiere dividir entre la parte de arriba y la parte de abajo, ni entre derecha e izquierda, jeje.

Resultado, con 9 líneas:

    *   
   ***   
  ***** 
 *******
*********
 *******
  ***** 
   ***   
    *   


Básicamente lo que hacemos es calcular el "punto medio" p de N (redondeo por exceso de N/2), para el caso N=9 sería p=5. Luego recorremos tanto i como j desde -p+1 hasta p-1, o sea, desde -4 hasta 4. El asterisco se imprime si abs(j) < p - abs(i), y esto dibuja el rombo de manera correcta, tanto en su parte superior como la inferior. El código:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void rombo (int N);
  5.  
  6. int main(void) {
  7.  
  8. int N;
  9.  
  10. printf("Ancho del rombo: ");
  11. scanf("%d", &N);
  12.  
  13. /* limpia la entrada estandar por caracteres no leidos */
  14. while ( getchar() != '\n' )
  15. ;
  16.  
  17. /* comprueba N impar y positivo */
  18. if ( N > 0 && (N % 2) == 1)
  19. rombo( N );
  20. else
  21. printf("N debe ser impar positivo\n");
  22.  
  23. return 0;
  24. }
  25.  
  26. /* Imprime un rombo de N lineas */
  27. void rombo (int N) {
  28.  
  29. int i, j, p;
  30.  
  31. p = (int) N / 2 + 1; /* punto medio ente 1 y N */
  32. for (i = -p + 1; i <= p - 1; i++) {
  33. for (j = -p + 1; j <= p - 1; j++)
  34. if ( abs(j) < p - abs(i) )
  35. putchar('*');
  36. else
  37. putchar(' ');
  38. putchar('\n');
  39. }
  40. }
190  Programación / Programación C/C++ / Re: tableros en: 5 Marzo 2014, 19:28 pm
"Yo, en particular, estoy muy contento con tus aportes ya que la mayoría de los expertos lo son más de C++ y a mí me interesa más el C puro y duro"

Jejeje, pues sí, es un dicho que entre más bajo el nivel más duro es el programador, jeje. De hecho me impongo como costumbre personal tratar de hacer los programas en C puro, salvo que sea estrictamente necesario usar C++ (por ejemplo si se requieren clases).

Ya tengo la respuesta (y creo que me quedó cool :laugh:). Bueno, es cuestión de probar con estos nuevos simbolitos, y tener paciencia hasta "cuadrar" el resultado. Yo te recomendaría anabelangie, definir mnemónicos o nombres simbólicos para los códigos ASCII a usar, de esa forma se trabaja de manera estructurada, y el código es más fácil de comprender y modificar en el futuro.

Siguiendo más o menos la nomenclatura que pude escudriñar en el fichero de cabecera [ncurses.h (el equivalente Linux para conio.h), me "copié" los nombres:

#define ULCORNER 218      /* upper-left corner, esquina superior izquierda */
#define URCORNER 191      /* upper-right corner, esquina superior derecha */
#define LLCORNER 192      /* lower-left corner, esquina inferior izquierda */
#define LRCORNER 217      /* lower-right corner, esquina inferior izquierda */
#define VLINE    179      /* vertical line, linea vertical */
#define HLINE    196      /* horizontal line, linea horizontal (guion) */
#define TTEE     193      /* top-tee, letra 'T' apuntando hacia arriba */
#define RTEE     195      /* right-tee, letra 'T' apuntando hacia la derecha */
#define BTEE     194      /* bottom-tee, letra 'T' apuntando hacia abajo */
#define LTEE     180      /* left-tee, letra 'T' apuntando hacia la izquierda */
#define CROSS    197      /* crossover, cruz grande (de mayor tamaño que el signo '+') */
#define TOKEN    219      /* ficha o pieza */

y disculpen el inglés, es sólo para hacerlo más universal. Lo demás es modificar el printBoard para que el diseño te quede como quieres. Claro, es más laborioso que con '+', '|' y '-', y requiere muchos más caracteres para producir el resultado  ... :rolleyes:

Los caracteres de la matriz A que sean distintos de un nulo '\0' y de un espacio se representarán como la ficha o TOKEN (ASCII 219). Queda la posibilidad de ampliar el programa para permitir varios diseños de fichas, según los caracteres simbólicos en A. El resultado:

┌───┬───┬───┬───┬───┬───┬───┬───┐
│ █ │ █ │ █ │   │ █ │ █ │   │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │ █ │   │   │ █ │   │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │ █ │   │ █ │   │ █ │   │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │ █ │ █ │ █ │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │   │ █ │ █ │   │ █ │ █ │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │   │   │ █ │ █ │ █ │ █ │   │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │
└───┴───┴───┴───┴───┴───┴───┴───┘


y el código fuente que lo produce:
Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. #define M 8
  5. #define N 8
  6.  
  7. /* Definiendo mnemonicos para los simbolos ASCII */
  8. #define ULCORNER 218 /* upper-left corner, esquina superior izquierda */
  9. #define URCORNER 191 /* upper-right corner, esquina superior derecha */
  10. #define LLCORNER 192 /* lower-left corner, esquina inferior izquierda */
  11. #define LRCORNER 217 /* lower-right corner, esquina inferior izquierda */
  12. #define VLINE    179 /* vertical line, linea vertical */
  13. #define HLINE    196 /* horizontal line, linea horizontal (guion) */
  14. #define TTEE     193 /* top-tee, letra 'T' apuntando hacia arriba */
  15. #define RTEE     195 /* right-tee, letra 'T' apuntando hacia la derecha */
  16. #define BTEE     194 /* bottom-tee, letra 'T' apuntando hacia abajo */
  17. #define LTEE     180 /* left-tee, letra 'T' apuntando hacia la izquierda */
  18. #define CROSS    197 /* crossover, cruz grande (de mayor tamaño que el signo '+') */
  19. #define TOKEN    219 /* ficha o pieza */
  20.  
  21. void fillRow( char **, int, const char *);
  22. void printBoard( char ** );
  23.  
  24. int main() {
  25.  
  26. char **A;
  27. int i;
  28.  
  29. /* Inicializa la matriz, y termina si ocurre error */
  30. if ( ( A = (char **) malloc ( M * sizeof(char *) ) ) == NULL )
  31. return -1;
  32. for (i = 0; i < M; i++ )
  33. if ( ( A[i] = (char *) malloc ( N * sizeof(char) ) ) == NULL )
  34. return -1;
  35.  
  36. fillRow( A, 0, "xxx xx x" );
  37. fillRow( A, 1, "x  x  x " );
  38. fillRow( A, 2, "x x x x " );
  39. fillRow( A, 3, "xxxxx   " );
  40. fillRow( A, 4, "xx      " );
  41. fillRow( A, 5, "xx xx xx" );
  42. fillRow( A, 6, "x  xxxx " );
  43. fillRow( A, 7, "xxxxxxxx" );
  44.  
  45. /* imprimir el tablero */
  46. printBoard( (char **)A );
  47.  
  48. return 0;
  49. }
  50.  
  51. /* Rellena la fila i de la matriz A con los elementos del vector x */
  52. void fillRow( char **A, int i, const char *x) {
  53.  
  54. int j;
  55.  
  56. for (j = 0; j < N; j++)
  57. A[i][j] = x[j];
  58. }
  59.  
  60. /* Imprime un tablero de 8x8, rellenando las casillas con los
  61.  * caracteres almacenados en la matriz A
  62.  */
  63. void printBoard( char **A ) {
  64.  
  65. int i, j;
  66. char c, *s;
  67.  
  68. printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", ULCORNER,
  69. HLINE, HLINE, HLINE, BTEE,
  70. HLINE, HLINE, HLINE, BTEE,
  71. HLINE, HLINE, HLINE, BTEE,
  72. HLINE, HLINE, HLINE, BTEE,
  73. HLINE, HLINE, HLINE, BTEE,
  74. HLINE, HLINE, HLINE, BTEE,
  75. HLINE, HLINE, HLINE, BTEE,
  76. HLINE, HLINE, HLINE, URCORNER);
  77. for (i = 0; i < M; i++) {
  78. putchar(VLINE);
  79. for (j = 0; j < N; j++)
  80. if ( A[i][j] != '\0' && A[i][j] != ' ')
  81. printf(" %c %c", 219, VLINE);
  82. else
  83. printf("   %c", VLINE);
  84. if ( i < M - 1 )
  85. /* todas las lineas excepto la ultima */
  86. printf("\n%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", RTEE,
  87. HLINE, HLINE, HLINE, CROSS,
  88. HLINE, HLINE, HLINE, CROSS,
  89. HLINE, HLINE, HLINE, CROSS,
  90. HLINE, HLINE, HLINE, CROSS,
  91. HLINE, HLINE, HLINE, CROSS,
  92. HLINE, HLINE, HLINE, CROSS,
  93. HLINE, HLINE, HLINE, CROSS,
  94. HLINE, HLINE, HLINE, LTEE);
  95. else
  96. /* la linea final */
  97. printf("\n%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", LLCORNER,
  98. HLINE, HLINE, HLINE, TTEE,
  99. HLINE, HLINE, HLINE, TTEE,
  100. HLINE, HLINE, HLINE, TTEE,
  101. HLINE, HLINE, HLINE, TTEE,
  102. HLINE, HLINE, HLINE, TTEE,
  103. HLINE, HLINE, HLINE, TTEE,
  104. HLINE, HLINE, HLINE, TTEE,
  105. HLINE, HLINE, HLINE, LRCORNER);
  106. }
  107.  
  108. }[/tt]
  109.  
  110.  



Ah, por cierto, yo trabajo en consola de Linux, y para que me pudiera representar correctamente los símbolos tuve que poner la codificación "IBM850", no me sirvió ISO-5589-1 ni UTF-8. No se si en Windows será lo mismo ... ¿alguien sabe qué pasa con ésto?  :huh:
Páginas: 1 ... 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [19] 20 21 22 23 24 25 26
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines