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

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


  Mostrar Mensajes
Páginas: 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
161  Programación / Programación C/C++ / Re: Problema con un programa en C (string.h y funciones) en: 11 Marzo 2014, 08:33 am
Totalmente de acuerdo engelx, pero también hay considerar a veces que no sólo el código fuente sea más breve, sino que realmente se ejecute más rápido.

Por ejemplo, usas tres veces el strlen(text) es decir una sobrecarga por llamadas a función. Sería mejor definir una constante y asignarle el valor N = strlen(text), luego usas N. Esto quizá lleve más líneas de código fuente pero se ejecutará más rápido.
162  Programación / Programación C/C++ / Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas? en: 11 Marzo 2014, 08:08 am
María, llega un momento en que la complejidad de un programa crece hasta que termina enredándose uno mismo en su propio trabajo, jeje. Para evitar eso debes trabajar de manera modular, es decir, divide el programa en pequeñas partes funcionales que puedan integrarse entre sí.

Ahora hago unos comentarios. Es muy válida la recomendación de eferion, si estás en C++ usa endl en lugar de '\n'. Por otra parte perdón a los que puedan discrepar pero me parece más lógico que la matriz sea considerada de enteros y no de char, pues al fin y al cabo contendrá números (1 si hay bomba, 0 si no hay). Soy partidario de que una función auxiliar sea la encargada de decidir qué caracteres se van a mostrar en pantalla, en lugar de que dichos caracteres sean almacenados directamente en la matriz. Y como verás, este enfoque te evitar tener que hacer conversiones y operaciones complicadas como:

Matriz[fil][col]=cont[fil][col]+48;   (????????)


Tomando como base el código que presentaste, y depurándolo eliminé unas cuántas líneas redundantes por aquí y por allá, también como te dije sacar del main() rutinas que pueden definirse aparte, hasta quedar un procedimiento principal breve, limpio y sencillo (como debe ser):
Código
  1. int main(void) {
  2.  
  3.   int dim;
  4.   int i, j;
  5.  
  6.   cout << "Introduzca la dimension de la matriz: ";
  7.   cin >> dim;
  8.  
  9.   int **A = new int *[dim];
  10.   for (i = 0; i < dim; i++)
  11.      A[i] = new int [dim];
  12.   for (i = 0; i < dim; i++)
  13.      for (int j = 0; j < dim; j++)
  14.         A[i][j] = 0;
  15.  
  16.   /* indicar donde van las minas, e imprimir */      
  17.   colocar_minas( A, dim);
  18.   imprimir( A, dim, 1);
  19.  
  20.   /* descubrir las casillas */
  21.   descubrir_casillas( A, dim);
  22. }
donde me tomé el atrevimiento de cambiar el nombre "Matriz" por simplemente "A".

Ahora, la función auxuliar de colocar las minas se encarga de rellenar la matriz (en lugar de hacerlo el main()). En lo particular me pareció un poco pesado e innecesario que el usuario tenga que decir de antemano cuántas bombas hay. En lugar de ello lo modifiqué para que él te vaya preguntando si quieres meter otra mina, y sigue hasta que respondas 'n'. El código:
Código
  1. void colocar_minas (int **A, int dim) {
  2.  
  3.   int i, fil, col;
  4.   char op;
  5.  
  6.   cout << endl << "*** Colocando las minas ***" << endl << endl;
  7.  
  8.   op = 's';
  9.   do {
  10.      do {
  11.         cout << "Introduzca fila: ";
  12.         cin >> fil;
  13.      } while (fil < 1 || fil > dim);
  14.      fil = fil - 1;
  15.  
  16.      do {
  17.         cout << "Introduzca columna: ";
  18.         cin >> col;
  19.      } while (col < 1 || col > dim);
  20.      col = col - 1;
  21.  
  22.      A[fil][col] = 1;
  23.  
  24.      /* imprimimos, para que el usuario vea como va quedando */
  25.      imprimir( A, dim, 0);
  26.  
  27.      do {
  28.         cout << "Otro? s/n: ";
  29.         cin >> op;
  30.      } while ( op != 's' && op != 'S' && op != 'n' && op != 'N' );
  31.  
  32.   } while ( op == 's' || op == 'S' );
  33. }

También me pareció más adecuado separar la utilidad de contar las minas que rodean una casilla en una función aparte int contar_minas( int **A, int dim, int i, int j ).

Ahora vamos a la parte delicada, y lo que creó el meollo: si en la matriz reemplazas el valor de cada casilla (1 si hay bomba y 0 si no hay) por la suma de las casillas adyacentes, entonces pierdes el valor original. ¿Cómo hacer? Una solución sería crear dos matrices, pero desperdicia espacio de memoria. Otra alternativa es modificar la función:

imprimir(int **A, int dim, int estilo)

que recibe una matriz A de 1's y 0's, pero donde el tercer argumento estilo permite definir tres modos posibles de funcionamiento:
  • estilo = 0, hace que se imprima '*' donde hay bomba y '0' donde no hay
  • estilo = 1, hace que se impriman las sumas de las casillas circundantes, en lugar de bomba/no-moba
  • estilo = 2, es para cuando el usuario va descubriendo las casillas. Imprime la suma circundante si la casilla no ha sido destapada, '0' si ha sido destapada y no hay bomba, y '*' si se destapó y hay una bomba (el juego termina).
La idea es usar el estilo 0 cuando estás rellenando la matriz, el 1 cuando terminaste de llenar, y el 2 cuando vas destapando las casillas. Pero resumes los tres en una sola función, de un modo sintético y elegante.

Sin embargo surge un problema delicado. Si una casilla no tiene bomba y no ha sido destapada se representa por la suma circundante. Pero si no tiene bomba y ha sido destapada, se representa por un '0'. ¿Cómo distinguir un caso de otro? Como dije antes una solución (ineficiente) es crear una segunda matriz que se vaya actualizando según las casillas que el usuario vaya descubriendo.
Mejor es apelar a un "truco" que usamos los programadores. Si miras bien, hasta ahora hemos usado 2 valores posibles para cada celda de la matriz A, esto es, 0 y 1. Quedan otros valores disponibles, con los que podemos representar otros significados. Podríamos asignar el valor -1 para la casilla que tenga una bomba que ha sido descubierta (boom!!, termina el juego), y el 2 para la casilla que ha sido destapada y no tiene bomba. Así quedaría:
  • A[ i][j] = -1, si hay una bomba y fue destapada (termina el juego)
  • A[ i][j] = 0, si no hay bomba, y no ha sido destapada
  • A[ i][j]) = 1, si hay bomba, pero no ha sido destapada
  • A[ i][j] = 2, si no hay bomba, y fue destapada
La función de imprimir, con las tres posibilidades quedaría:
Código
  1. void imprimir( int **A, int dim, int estilo) {
  2.  
  3.   int i, j;
  4.  
  5.   for (i = 0; i < dim; i++) {
  6.   cout << "\t\t" ;
  7.      for (j = 0; j < dim; j++) {
  8.         /* aqui decidimos como queremos imprimir */
  9.         switch (estilo) {
  10.            /* solo mina / no-mina */
  11.            case 0:
  12.               if ( A[i][j] == 1 )
  13.                  cout << " * ";
  14.               else
  15.                  cout << " 0 ";
  16.               break;
  17.            /* contar las minas que rodean */
  18.            case 1:
  19.               cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  20.               break;
  21.            /* a medida se van descubriendo las minas */
  22.            case 2:
  23.               if ( A[i][j] == -1 )
  24.                  cout << " * ";      /* boom, jeje */
  25.               else if ( A[i][j] == 0 || A[i][j] == 1 )  
  26.                  cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  27.               else if ( A[i][j] == 2 )
  28.                  cout << " 0 ";
  29.            break;
  30.         }
  31.      }
  32.      cout << endl << endl;
  33.   }
  34.   cout << endl << endl;
  35. }

Ahora, hay que tener cuidado cuando codificamos la función de sumar los adyacentes. Recuerda que se debe sumar cualquier bomba (destapada o no) o sea, el valor 1 ó -1 en la matriz. Por lo tanto:
Código
  1. /* Cuenta la cantidad de minas que rodean a una posicion dada de la matriz,
  2.  * incluyendo al elemento propio */
  3. int contar_minas( int **A, int dim, int i, int j ) {
  4.  
  5.   int k, l, contador;
  6.  
  7.   contador = 0;
  8.   for ( k = -1; k < 2; k++) {
  9.      for ( l = -1; l < 2; l++) {
  10.         if (i+k >= 0 && j+l >= 0 && i+k < dim && j+l < dim)
  11.            if ( A[i+k][j+l] == 1 || A[i+k][j+l] == -1)
  12.               contador ++;
  13.      }
  14.   }
  15.  
  16.   return contador;
  17. }

Ya lo que quedaría sería definir la función que permite al usuario ir destapando las casillas a su gusto. Si destapa una bomba, pierde. De lo contrario, el juego continúa hasta que destapa todas las que no tienen bomba en cuyo caso gana. Este código te lo muestro al final, junto con el programa completo.

El código a continuación ya es funcional, está listo para copiar, compilar y ejecutar.

NOTA. Téngase en cuenta que en el juego buscaminas real hay características que nuestro programa aún no posee.

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. void imprimir (int **A, int dim, int estilo);
  6. void colocar_minas (int **A, int dim);
  7. int contar_minas (int **A, int dim, int i, int j);
  8. void descubrir_casillas (int **A, int dim);
  9.  
  10. int main(void) {
  11.  
  12.   int dim;
  13.   int i, j;
  14.  
  15.   cout << "Introduzca la dimension de la matriz: ";
  16.   cin >> dim;
  17.  
  18.   int **A = new int *[dim];
  19.   for (i = 0; i < dim; i++)
  20.      A[i] = new int [dim];
  21.   for (i = 0; i < dim; i++)
  22.      for (int j = 0; j < dim; j++)
  23.         A[i][j] = 0;
  24.  
  25.   /* indicar donde van las minas, e imprimir */      
  26.   colocar_minas( A, dim);
  27.   imprimir( A, dim, 1);
  28.  
  29.   /* descubrir las casillas */
  30.   descubrir_casillas( A, dim);
  31. }
  32.  
  33. /* Permite al usuario ir colocando las minas. Para seguir colocando,
  34.  * responder 's' al final, de lo contrario termina. */
  35. void colocar_minas (int **A, int dim){
  36.  
  37.   int i, fil, col;
  38.   char op;
  39.  
  40.   cout << endl << "*** Colocando las minas ***" << endl << endl;
  41.  
  42.   op = 's';
  43.   do {
  44.      do {
  45.         cout << "Introduzca fila: ";
  46.         cin >> fil;
  47.      } while (fil < 1 || fil > dim);
  48.      fil = fil - 1;
  49.  
  50.      do {
  51.         cout << "Introduzca columna: ";
  52.         cin >> col;
  53.      } while (col < 1 || col > dim);
  54.      col = col - 1;
  55.  
  56.      A[fil][col] = 1;
  57.  
  58.      /* imprimimos, para que el usuario vea como va quedando */
  59.      imprimir( A, dim, 0);
  60.  
  61.      do {
  62.         cout << "Otro? s/n: ";
  63.         cin >> op;
  64.      } while ( op != 's' && op != 'S' && op != 'n' && op != 'N' );
  65.  
  66.   } while ( op == 's' || op == 'S' );
  67. }
  68.  
  69. /* Imprime la matriz en varios estilos:
  70.  *
  71.  *  0: Indican simplemente donde hay minas y donde no.
  72.  *  1: Indica cuantas minas rodean a cada casilla (incluyendo a si misma)
  73.  *  2: Como se muestra a medida que se descubren las casillas.
  74.  *     El valor -1 imprime una bomba, para los valores entre 0 y 9 imprimen
  75.  *     la suma circundante, y el 10 se imprime como 0.
  76.  */
  77. void imprimir( int **A, int dim, int estilo) {
  78.  
  79.   int i, j;
  80.  
  81.   for (i = 0; i < dim; i++) {
  82.   cout << "\t\t" ;
  83.      for (j = 0; j < dim; j++) {
  84.         /* aqui decidimos como queremos imprimir */
  85.         switch (estilo) {
  86.            /* solo mina / no-mina */
  87.            case 0:
  88.               if ( A[i][j] == 1 )
  89.                  cout << " * ";
  90.               else
  91.                  cout << " 0 ";
  92.               break;
  93.            /* contar las minas que rodean */
  94.            case 1:
  95.               cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  96.               break;
  97.            /* a medida se van descubriendo las minas */
  98.            case 2:
  99.               if ( A[i][j] == -1 )
  100.                  cout << " * ";      /* boom, jeje */
  101.               else if ( A[i][j] == 0 || A[i][j] == 1 )  
  102.                  cout << ' ' << contar_minas( A, dim, i, j ) << ' ';
  103.               else if ( A[i][j] == 2 )
  104.                  cout << " 0 ";
  105.            break;
  106.         }
  107.      }
  108.      cout << endl << endl;
  109.   }
  110.   cout << endl << endl;
  111. }
  112.  
  113. /* Cuenta la cantidad de minas que rodean a una posicion dada de la matriz,
  114.  * incluyendo al elemento propio */
  115. int contar_minas( int **A, int dim, int i, int j ) {
  116.  
  117.   int k, l, contador;
  118.  
  119.   contador = 0;
  120.   for ( k = -1; k < 2; k++) {
  121.      for ( l = -1; l < 2; l++) {
  122.         if (i+k >= 0 && j+l >= 0 && i+k < dim && j+l < dim)
  123.            if ( A[i+k][j+l] == 1 || A[i+k][j+l] == -1)
  124.               contador ++;
  125.      }
  126.   }
  127.  
  128.   return contador;
  129. }
  130.  
  131. /* Permite al usuario ir descubriendo casillas del tablero, y si se
  132.  * encuentra una mina, pierde !!! */
  133. void descubrir_casillas( int **A, int dim ) {
  134.  
  135.   int i, j;
  136.   char terminar;
  137.  
  138.   cout << endl << "*** Ahora descubriendo las casillas ***" << endl << endl;
  139.  
  140.   imprimir( A, dim, 2);
  141.  
  142.   terminar = 'n';
  143.   do {
  144.      do {
  145.         cout << "Introduzca fila: ";
  146.         cin >> i;
  147.      } while (i < 1 || i > dim);
  148.      i = i - 1;
  149.  
  150.      do {
  151.         cout << "Introduzca columna: ";
  152.         cin >> j;
  153.      } while (j < 1 || j > dim);
  154.      j = j - 1;
  155.  
  156.      if ( A[i][j] == 1) {
  157.         /* encuentra mina: pierde !!! */
  158.         A[i][j] = -1;
  159.         imprimir( A, dim, 2 );
  160.         cout << endl << "Boom!!!, ha perdido" << endl;
  161.         terminar = 's';
  162.      }
  163.      else {
  164.         /* sigue jugando */
  165.         A[i][j] = 2;
  166.         imprimir( A, dim, 2 );
  167.      }
  168.  
  169.      /* Nota: 0 significa casilla sin bomba y sin descubrir.
  170.        *       2 significa casilla sin bomba y ya descubierta.
  171.       /* El programa termina si no quedan por descubrir casillas
  172.        * sin bombas (casillas con el valor 0) */
  173.      if ( terminar == 'n' ) {
  174.         terminar = 's';
  175.         for (i = 0; terminar == 's' && i < dim; i++)
  176.            for (j = 0; terminar == 's' && j < dim; j++)
  177.               if ( A[i][j] == 0 ) terminar = 'n';
  178.  
  179.         if ( terminar == 's' ) {
  180.            cout << endl << "Felicitaciones, ha ganado !!!" << endl;
  181.            imprimir( A, dim, 0);
  182.         }
  183.      }
  184.  
  185.   } while ( terminar == 'n' );
  186. }
163  Programación / Programación C/C++ / Re: Problema con un programa en C (string.h y funciones) en: 11 Marzo 2014, 04:54 am
Uy, engelx se me adelantó, justo con la idea de interrupir el ciclo cuando ya se sepa que no es palíndromo. Lo que faltaría es recorrer sólo la primera mitad de la palabra, yeah!!
164  Programación / Programación C/C++ / Utilería, reemplazar TAB por " " en: 11 Marzo 2014, 04:15 am
Hola, comparto un programilla que puede ser útil en este mismo foro. Encuentro que al subir código con la etiqueta code, los tabuladores son reemplazados por una cantidad de espacios que a mi entender son demasiados (son como 8). El código entonces toma una aparienci anti-estética  :-\. Se me ocurrió hacer un programa llamado "tab" que reemplace todos los TAB en el fichero .c original por una cantidad de espacios determinada, y vuelque su salida a un fichero auxiliar, cuyo contenido copiaré dentro de la etiqueta code.

La sintaxis (UNIX)

./tab fichero_entrada fichero_salida N_spaces

y en DOS quitar el "./" que antecede a tab. Por ejemplo, "tab code.c code2.c 3". Si no se indica N_spaces se toman 3, y si no se indica fichero de salida toma la salida estándar.

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. /* Este programa reemplaza los caracteres TAB del fichero de texto
  5.  * pasado como primer argumento por una cantidad determinada de espacios,
  6.  * y escribe su salida en el fichero pasado como segundo argumento.
  7.  * El tercer argumento (opcional) especifica cuántos caracteres ' '
  8.  * reemplazarán el TAB, y si no se indica, se tomará una cantidad de tres.
  9.  */
  10.  
  11. int main( int argc, char *argv[]) {
  12.  
  13.   int i, N_spaces;
  14.   char c;
  15.   char * in_fname, * out_fname;
  16.   FILE * in_fptr = NULL, * out_fptr = NULL;
  17.  
  18.   if ( argc < 2 ) {
  19.      printf("Use:\n tab in_file out_file\n tab in_file out_file N_spaces\n");
  20.      goto failure;
  21.   }
  22.  
  23.   in_fname = argv[1];
  24.  
  25.   if ( argc > 3 ) {
  26.      N_spaces = atoi( argv[3] );
  27.      if ( N_spaces < 1 )
  28.         N_spaces = 3;
  29.      }
  30.   else
  31.      N_spaces = 3;
  32.  
  33.   if ( ( in_fptr = fopen( in_fname, "r" ) ) == NULL ) {
  34.      printf( "No existe o no se pudo abrir '%s'\n", in_fname );
  35.      goto failure;
  36.   }
  37.  
  38.   /* toma stdout si falta fichero de salida */
  39.   if ( argc < 3 )
  40.      out_fptr = stdout;
  41.   else   {
  42.      out_fname = argv[2];
  43.      if ( ( out_fptr = fopen( out_fname, "w" ) ) == NULL ) {
  44.         printf( "Imposible crear, abrir o escribir en '%s'\n", out_fname );
  45.         goto failure;
  46.      }
  47.   }
  48.  
  49.   /* reemplazando TAB por N_spaces caracteres ' ' */
  50.   while ( ( c = fgetc( in_fptr ) ) != EOF ) {
  51.      if ( c != '\t' )
  52.         fputc( c, out_fptr );
  53.      else
  54.         for ( i = 0; i < N_spaces; i++ )
  55.            fputc( ' ', out_fptr );
  56.   }
  57.  
  58.   if ( in_fptr != NULL ) fclose( in_fptr);
  59.   if ( out_fptr != NULL ) fclose( out_fptr);
  60.   return 0;
  61.  
  62. failure:
  63.   if ( in_fptr != NULL ) fclose( in_fptr);
  64.   if ( out_fptr != NULL ) fclose( out_fptr);
  65.   return -1;
  66. }

NOTA. Una alternativa es la utilería "sed" (UNIX), pero no se si tiene alternativa Windows.
165  Programación / Programación C/C++ / Re: Problema con un programa en C (string.h y funciones) en: 11 Marzo 2014, 03:43 am
Exactamente como dice leosasan, faltaba la parte donde realmente inviertes la palabra (?!). Y aparte yo recomendaría optimizar la parte donde haces la comparación, sin necesidad de usar la variable intermedia j (entre menos variables uses, el código será más ligero):
Código
  1. if( strcmp(text2, text) != 0 )
  2.    printf("\n Es un palindromo ");
  3. else
  4.    printf("\n No es un palindromo ");
  5. }

o más elegantemente, reemplazado strcmp(text2, text) != 0 por  !strcmp(text2, text) :
Código
  1. if( !strcmp(text2, text) )
  2.    printf("\n Es un palindromo ");
  3. else
  4.    printf("\n No es un palindromo ");
  5. }

=====================================================
(EDICIÓN)

Estaba pensando mejor el asunto, y no es necesario invertir toda la palabra para saber si es un palindromo. Es decir, basta que un carácter no coincida con su "complementario" en la otra mitad de la palabra. O sea si la palabra tiene una longitud N entonces basta que
Código
  1. text[i] != text[N - i - 1]
para saber que no es palíndromo, y en este punto el ciclo debería detenerse. Por la misma razón, es suficiente con escanear la primera mitad de la palabra, o sea desde i=0 y mientras i sea menor a N/2 caracteres (saca la cuenta, funciona con N par e impar).

Con todo esto, el código se puede depurar a:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int palindromo (char text[]);
  5.  
  6. int main ()
  7. {
  8.  
  9.   char text[100];
  10.  
  11.   printf("\n Introduce un texto: ");
  12.   gets(text);
  13.  
  14.   if ( palindromo(text) )
  15.     printf("\n Es un palindromo ");
  16.   else
  17.     printf("\n No es un palindromo ");
  18.  
  19.   printf("\n FIN DEL PROGRAMA \n ");
  20.   getchar( );
  21.  
  22.   return 0;
  23. }
  24.  
  25. int palindromo (char text[])
  26. {
  27.   int i, N;
  28.  
  29.   N = strlen(text);
  30.   for (i = 0; i < (float)N/2; i++)
  31.   {
  32.      if ( text[i] != text[N - i - 1] )
  33.         return 0;
  34.   }
  35.   return 1;
  36. }

Claro, entre más sofisticado se vuelva el código puede que este se ejecute más rápido pero aumenta la complejidad de algunos detalles del mismo (espero no abrumarte). Observa que el tipo de retorno de la función auxiliar palindromo se cambió a int, precisamente para que devuelva un valor numérico indicando si la palabra es palindromo o no.

Si no lo es, observa que la ejecución del for/ se detiene en algún momento cuando la condición dentro del if sea verdadera, y retorna 0. De lo contrario, continúa hasta el final y retorna 1.

Por último un detalle sutil. Cuando la longitud N de la palabra sea impar, el cociente N/2 será decimal, pero los tipos de las variables i, N son enteros, por eso la comparación i < N/2 no será válida. Es necesario convertir N a float para que admita los decimales y por eso ponemos i < (float)N / 2.

Por ejemplo, si N=5 entonces el programa debe ejecutarse con las primeras 3 letras de la palabra, y siendo N/2 = 2.5 ocurrirá justo así, se ejecutará para i=0, i=1, i=2. Por eso, funciona bien cuando N es impar.
166  Programación / Programación C/C++ / Re: Recibir int seguro en: 11 Marzo 2014, 03:29 am
Leo, tu programa es ideal para el caso de una clave numérica con una cantidad exacta de dígitos, además obliga al usuario sobre meter exactamente esa cantidad.

Y respecto a los rombos, ....... tranquilo jaja que ya voy a aparecer con una idea que he estado pensando y espero sorprendente  ;D (tanto como las de todos)
167  Programación / Programación C/C++ / Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas? en: 11 Marzo 2014, 02:42 am
Ojo, leosansan, no había leído bien los mensajes previos tuyos y de eferion, sin embargo para que no haya confusión aclaro que en el juego que diseñé los asteriscos son MINAS.

Es más, voy a tener que usar unos #defines para especificar los distintos símbolos, así se pueden cambiar facílito de una versión a otra, jajaja

Yo no tengo en el mío casillas bloqueadas (inseleccionables), aunque esa funcionalidad se puede añadir.

En todo lo demás que has dicho sobre las características del juego buscaminas real, estoy de acuerdo!
168  Programación / Programación C/C++ / Re: Sobre la lectura de variables... en: 11 Marzo 2014, 02:38 am
Hola!!! Bueno, en C++ no conozco un método que no sea el propuesto por leosansan.

Pero hurgando en los papeles encontré una función de biblioteca de C llamada strtok() (requiere <string.h>) que me despertó curiosidad. Funciona precisamente en casos como éstos, su finalidad es "dividir una cadena en componentes léxicos". Sea la cadena s1, que se quiere dividir en componente léxicos, por medio de un token separador dado por la cadena (no carácter) s2. Entonces la llamada

strtok(s1, s2);

extrae de s1 el primer componente léxico, hasta llegar al token delimitador (o al final de s1 si no se encontró dicho delimitador). La función devuelve una cadena que corresponde al componente extraído. Las llamadas subsiguientes a strtok() deben hacerse con NULL como primer argumento, y de allí en adelante se siguen extrayendo los siguientes componentes de la cadena, devolviendo NULL cuando no existan más de ellos.

En el ejemplo a continuación el usuario introduce cualquier secuencia como "1,2,3,4", y el programa devuelve las distintas divisiones encontradas de la cadena, según el delimitador ","

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int main() {
  6.  
  7. char buf[101];
  8. char *s;
  9.  
  10. scanf( "%s", buf );
  11.  
  12. if ( ( s = strtok( buf, ",") ) != NULL )           /* primer componente */
  13. printf( "%s\n", s );
  14. while ( ( s = strtok( NULL, ",") ) != NULL )  /* restantes, hasta llegar al final */
  15. printf( "%s\n", s1 );
  16. }

===========================================
(EDITO)

A propósito del tema, estaba revisando que la función strtok(char* s1, const char *s2) acepta en s2 una cadena donde cualquiera de sus caracteres puede funcionar como delimitador. Esto puede aumentar la potencia del programa, por ejemplo si s2=",." entonces cualquiera de los caracteres coma o punto será un delimitador. El programa con la entrada "1,2.3.4" separará en 1, 2, 3, 4
Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. int main() {
  6.  
  7.   char buf[101];
  8.   char *s1;
  9.  
  10.   scanf( "%s", buf );
  11.  
  12.   if ( ( s1 = strtok( buf, ",.") ) != NULL )
  13.      printf( "%s\n", s1 );
  14.   while ( ( s1 = strtok( NULL, ",.") ) != NULL )
  15.      printf( "%s\n", s1 );
  16. }

NOTA. No funciona el espacio como separador debido a scanf(). Si se reemplaza por fgets() sí lo podría aceptar.
169  Programación / Programación C/C++ / Re: [SOLUCIONADO] Generar nombre aleatorio. en: 11 Marzo 2014, 02:13 am
Leo, ¿En serio se me olvidó el return de main()? Jaja, pero que burdo, sorry  :-[ !!!

Pero de veras que el programa está divertido, provoca fajarse a jugar contra la máquina, jaja.
Bueno, con las modificaciones que propones (contador de ganadas, perdidas y empatadas), quedaría:

Código
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <ctime>
  4.  
  5. void clear_screen( void );
  6.  
  7. using namespace std;
  8.  
  9. int main () {
  10.  
  11.   string human, machine;
  12.   int human_op = 0;      /* 1: tijera, 2: piedra, 3: papel */
  13.   int machine_op = 0;
  14.   char next;            /* next == 's' indica que se quiere seguir jugando */
  15.   int ganadas, perdidas, empates;
  16.  
  17.   /* Declarar matriz de casos:
  18.     *
  19.     * 1: tijera, 2: piedra, 3: papel
  20.     *
  21.     * El elemento (i,j) vale:
  22.     *   1 si "i le gana a j"
  23.     *  -1 si "i pierde ante j"
  24.     *   0 si hay empate
  25.     */
  26.   int A[3][3] = {{0, -1, 1}, {1, 0, -1}, {-1, 1, 0}};
  27.  
  28.   /* inicializar semilla */
  29.   srand( time(NULL) );
  30.   ganadas = perdidas = empates = 0;
  31.  
  32.   do {
  33.  
  34.      /* El humano elige */
  35.      do {
  36.         clear_screen( );      /* borrar pantalla */
  37.         cout << "Juego piedra, papel o tijera ..." << endl << endl
  38.            << "1: tijera" << endl
  39.            << "2: piedra" << endl
  40.            << "3: papel" << endl << endl
  41.            << "elige: ";
  42.         cin >> human_op;
  43.      } while ( human_op < 1 || human_op > 3 );
  44.      switch ( human_op ) {
  45.         case 1:
  46.            human = "tijera";
  47.            break;
  48.         case 2:
  49.            human = "piedra";
  50.            break;
  51.         case 3:
  52.            human = "papel";
  53.            break;
  54.      }
  55.  
  56.      /* La máquina elige */
  57.      machine_op = rand( ) % 3 + 1;
  58.      switch ( machine_op ) {
  59.         case 1:
  60.            machine = "tijera";
  61.            break;
  62.         case 2:
  63.            machine = "piedra";
  64.            break;
  65.         case 3:
  66.            machine = "papel";
  67.            break;
  68.      }
  69.  
  70.      /* Ahora se decide quien gana */
  71.      cout << endl << "Usted elige: " << human << endl
  72.         << "La maquina elige: " << machine << endl << endl
  73.         << "... ";
  74.      switch ( A[human_op - 1][machine_op - 1] ) {
  75.         case 1:
  76.            cout << "Usted gana !!!" << endl;
  77.            ganadas++;
  78.            break;
  79.         case -1:
  80.            cout << "Ups, usted pierde" << endl;
  81.            perdidas++;
  82.            break;
  83.         case 0:
  84.            cout << "Empate" << endl;
  85.            empates++;
  86.            break;
  87.      }
  88.  
  89.      /* Seguir jugando ? */
  90.      cout << ganadas << " ganadas, " << perdidas << " perdidas, "
  91.         << empates << " empates" << endl << endl;
  92.      cout << "Seguir jugando s/n? ";
  93.      cin >> next;
  94.   } while ( next == 's' );
  95.  
  96.   return 0;
  97. }
  98.  
  99. /* Borra la pantalla */
  100. void clear_screen( void ) {
  101.  
  102.   /* para Windows */
  103.   //system( "cls" );
  104.   /* para Linux */
  105.   system( "clear" );
  106. }

170  Programación / Programación C/C++ / Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas? en: 10 Marzo 2014, 01:29 am
Hola María. Compatriota!!!, entiendo tu situación pues también soy de Vzla y es triste la situación que vivimos. Los poderosos explotando a los débiles  >:(, no importa el lado político en que se midan.

Leo, lo que quiero decir más específicamente es que el totalitarismo de derecha (Pinochet, Franco, Mussolini) y el de izquierda (Stalin, Fidel, Chávez) son lo mismo; al final sólo pisotear y explotar al pueblo. Robar a manos llenas, porque TODOS sin importar su lado político se hacen ricos y amasan enormes fortunas en el exterior, mientras el pueblo pasa trabajo. Aunque seas un profesional, igual no te alcanza para vivir. En Venezuela estamos mal, mal, mal .... la GN reprime y maltrata a la gente, a algunos los han lesionado, quemado, golpeado, secuestrado, perdido un ojo, y otros han perdido la vida. No hay comida. No se puede salir del país porque no hay Aerolíneas (el gobierno les debe una fortuna y suspendieron el servicio) y es un problema para otorgar los dólares o euros. Así que ni soñar con visitar un días las Canarias. Por cierto, ¿cómo es la situación allá? Espero que mejor que aquí, y si pensabas venir algún día a Vzla no lo hagas en este momento porque al saber que eres extranjero capaz y te acusan de agente de la CIA y te llevan preso.

Y agradezco la solidaridad de ustedes los Canarios, yo creo que la cultura Hispana, Canaria y Latinoamericana se parece mucho. Por cierto, ¿Canarios y Españoles peninsulares se llevan bien o mal entre sí?

Respecto al buscaminas pareces adivinar porque justamente tuve que buscar en google ya que se me había olvidado como se jugaba, jaja. Corrí tu programa y perfecto!!!, ahora sólo hace falta la parte dónde se desarrolla el juego en sí, o sea, se van descubriendo las minas. Por eso le pregunté a María si se puede usar getch() ya que en ese caso el juego sería más interactivo y nos podemos ir  desplazando por directamente por las casillas en lugar que estar preguntando coordenadas  :huh:
Páginas: 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
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines