Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Triper0 en 26 Julio 2011, 20:53 pm



Título: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 20:53 pm
Bueno, mi problema es el siguiente:
Desde que empecé con C, el profesor me recomendó usar Linux.
El tema es que SIEMPRE que uso punteros, y toco la memoria, cuando compilo me sale "Violación de segmento"...

El profesor me dijo "El problema no es Linux, el problema es el programador" ¬¬

En fin, no encuentro ayuda, sé que estoy haciendo algo mal, pero no sé qué... Sé que Linux no te deja tocar la memoria como si lo hace Windows (el cual no me genera problema con esto)...

En fin, acá dejo un código que justo estaba haciendo hoy, es muy simple, compila excelente, pero dice el famoso "violación de segmento"...

Código:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
char *nombre;
char *apellido;
char *fecha;
char *legajo;
char *tipDoc;
int DNI;
}Alumno;

int main(){
Alumno alu,alu2;
malloc(sizeof(alu.nombre));
malloc(sizeof(alu.apellido));
malloc(sizeof(alu.fecha));
malloc(sizeof(alu.legajo));
malloc(sizeof(alu.tipDoc));
strcpy(alu.nombre,"Esteban");
strcpy(alu.apellido,"Gonzalez");
strcpy(alu.fecha,"02111991");
strcpy(alu.legajo,"10662/3");
strcpy(alu.tipDoc,"DNI");
alu.DNI=36363023;

malloc(sizeof(alu2.nombre));
malloc(sizeof(alu2.apellido));
malloc(sizeof(alu2.fecha));
malloc(sizeof(alu2.legajo));
malloc(sizeof(alu2.tipDoc));

alu2=alu;

printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
printf("El DNI del alu es: %d, el de alu2 es: %d\n\n\n",alu.DNI,alu2.DNI);

strcpy(alu.nombre,"Jose");

printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
printf("El DNI del alu es: %d, el de alu2 es: %d\n",alu.DNI,alu2.DNI);

return 0;
}


Gracias de antemano...


Título: Re: Problema con violación de segmento
Publicado por: leogtz en 26 Julio 2011, 21:13 pm
Todas las líneas de malloc están mal, malloc es una función que devuelve un puntero a la memoria asignada, por lo cual deberías asignarlo a la variable que intentas asignarle espacio.


Título: Re: Problema con violación de segmento
Publicado por: satu en 26 Julio 2011, 21:42 pm
Hola

Además de que estás reservando el tamaño de un puntero

Saludos


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 21:45 pm
Desde ya, MUCHÍSIMAS gracias, me ha vuelto loco durante todo el seminario este error... Ahora ya no me lo tira más, acá dejo el código modificado para que me digan si de la forma que lo solucioné está bien o es una falta de respeto a los ojos de un programador de C :P

Código:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
char *nombre;
char *apellido;
char *fecha;
char *legajo;
char *tipDoc;
int DNI;
}Alumno;

int main(){
Alumno alu,alu2;
alu.nombre= malloc(sizeof(alu.nombre));
alu.apellido= malloc(sizeof(alu.apellido));
alu.fecha= malloc(sizeof(alu.fecha));
alu.legajo= malloc(sizeof(alu.legajo));
alu.tipDoc= malloc(sizeof(alu.tipDoc));
strcpy(alu.nombre,"Esteban");
strcpy(alu.apellido,"Gonzalez");
strcpy(alu.fecha,"02111991");
strcpy(alu.legajo,"10662/3");
strcpy(alu.tipDoc,"DNI");
alu.DNI=36363023;

alu2.nombre= malloc(sizeof(alu2.nombre));
alu2.apellido= malloc(sizeof(alu2.apellido));
alu2.fecha= malloc(sizeof(alu2.fecha));
alu2.legajo= malloc(sizeof(alu2.legajo));
alu2.tipDoc= malloc(sizeof(alu2.tipDoc));

alu2=alu;

printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
printf("El DNI del alu es: %d, el de alu2 es: %d\n\n\n",alu.DNI,alu2.DNI);

strcpy(alu.nombre,"Jose");

printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
printf("El DNI del alu es: %d, el de alu2 es: %d\n",alu.DNI,alu2.DNI);

return 0;
}


Título: Re: Problema con violación de segmento
Publicado por: Dark Invader en 26 Julio 2011, 22:03 pm
Ahora estaría bien,te faltaba el cast:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. typedef struct {
  6. char *nombre;
  7. char *apellido;
  8. char *fecha;
  9. char *legajo;
  10. char *tipDoc;
  11. int DNI;
  12. }Alumno;
  13.  
  14. int main(){
  15. Alumno alu,alu2;
  16. alu.nombre= (char *)malloc(sizeof(alu.nombre));
  17. alu.apellido= (char *)malloc(sizeof(alu.apellido));
  18. alu.fecha= (char *)malloc(sizeof(alu.fecha));
  19. alu.legajo= (char *)malloc(sizeof(alu.legajo));
  20. alu.tipDoc= (char *)malloc(sizeof(alu.tipDoc));
  21. strcpy(alu.nombre,"Esteban");
  22. strcpy(alu.apellido,"Gonzalez");
  23. strcpy(alu.fecha,"02111991");
  24. strcpy(alu.legajo,"10662/3");
  25. strcpy(alu.tipDoc,"DNI");
  26. alu.DNI=36363023;
  27.  
  28. alu2.nombre= (char*) malloc(sizeof(alu2.nombre));
  29. alu2.apellido= (char*)malloc(sizeof(alu2.apellido));
  30. alu2.fecha= (char *)malloc(sizeof(alu2.fecha));
  31. alu2.legajo= (char*)malloc(sizeof(alu2.legajo));
  32. alu2.tipDoc= (char*)malloc(sizeof(alu2.tipDoc));
  33.  
  34. alu2=alu;
  35.  
  36. printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
  37. printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
  38. printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
  39. printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
  40. printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
  41. printf("El DNI del alu es: %d, el de alu2 es: %d\n\n\n",alu.DNI,alu2.DNI);
  42.  
  43. strcpy(alu.nombre,"Jose");
  44.  
  45. printf("El nombre del alu es: %s, el de alu2 es: %s\n",alu.nombre,alu2.nombre);
  46. printf("El apellido del alu es: %s, el de alu2 es: %s\n",alu.apellido,alu2.apellido);
  47. printf("La fecha del alu es: %s, el de alu2 es: %s\n",alu.fecha,alu2.fecha);
  48. printf("El legajo del alu es: %s, el de alu2 es: %s\n",alu.legajo,alu2.legajo);
  49. printf("El tipo de documento del alu es: %s, el de alu2 es: %s\n",alu.tipDoc,alu2.tipDoc);
  50. printf("El DNI del alu es: %d, el de alu2 es: %d\n",alu.DNI,alu2.DNI);
  51.  
  52. return 0;
  53. }

Por cierto,una sugerencia,yo la fecha la pondria como int mas que como char... :rolleyes:

Un saludo


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 22:08 pm
Gracias, gracias y nuevamente MIL gracias...

Con el tema de la fecha... Cuando lo pongo en int, long int o cualquier int que se me ocurra me tira el siguiente error de compilación:

Citar
error: invalid digit "9" in octal constant

Me suena rarisimo, no sé porqué dice que es octal, porque nada que ver... Por eso lo hice como cadena :P


Título: Re: Problema con violación de segmento
Publicado por: naderST en 26 Julio 2011, 22:14 pm
La fecha déjala char* porque como piensas asignar 26/07/11 en un int? lo de octal es porque si le asignas a un int esto 09 el tomará el numero como octal y los números octales no incluyen el 9 (0-7).


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 22:20 pm
Claro, vos decís que el error de octal me lo toma por el primer '0' del número?...
Claro, no lo pensé a eso...

De todas formas si, el hecho de las '/' es importante, aunque no hice una cadena muy grande como para que entren, jaja...
Igual son ejercicios pavos que estoy re/haciendo porque rindo un parcial y empecé de 0, jaja... Hay muchas cosas que las tenía bastante oxidadas :P

Ya de paso hago otra consulta:
Por ejemplo, yo definí una macro, supongamos:

#define T_INT 1;

si yo después, a esa macro la quiero comparar con una variable de tipo int también, que previamente fue ingresado su valor por teclado, ¿cómo se haría?...
Porque yo hice

if (valor == T_INT)
  printf("te imprimo algo");

y me tira error : error: expected ‘)’ before ‘;’ token

Código:
#define T_INT 1;
#define T_FLOAT 2;
#define T_STR 3;

union T_union{
int ival;
float fval;
char *sval;
};

int main(){
int valor;
union T_union u;
u.ival=22;
u.fval=22.69;
u.sval=(char *)malloc(sizeof(u.sval));
strcpy(u.sval,"NO ME LEAS");

printf("Ingrese un valor para invocar la lectura:\t");
scanf("%d\n",&valor);

if (valor == T_INT)
printf("El valor de ival es: %d\n",u.ival);
if (valor == T_FLOAT)
printf("El valor de fval es: %f\n",u.fval);
if (valor == T_STR)
printf("El contenido de sval es: %s\n",u.sval);

return 0;
}

Ahí dejé el código para complicar menos las cosas...


Título: Re: Problema con violación de segmento
Publicado por: Dark Invader en 26 Julio 2011, 22:22 pm
Edito:ya lo explico el compañero naderST  :P

De todos modos eso seria todo segun veo,si quieres puedes utilizar al operador new para asignar memoria,es de C++ pero es mas simple de asignar,aunque claro si el profe te dice que uses C yo no voy a decir lo contrario,asique dejaria el code asi si nadie tiene algo que añadir.

PD:Asignar la fecha como int a --->26072011,queda mas chapuzas pero bueno...Ademas no lo he probado,lo estoy diciendo por intuicion mas que otra cosa...xD

Un saludo


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 22:26 pm
Si, es un seminario de lenguaje C, no nos permiten ni C++ ni C#.
Es más, nos hicieron hacer un trabajo final de manejos de .BMP y nos hicieron hacer todo por nuestra cuenta, nada de usar funciones predefinidas de BMP ni nada, todo manual...
Aprendí bastante, pero fue un dolor de cabeza importante, jaja...


Título: Re: Problema con violación de segmento
Publicado por: Dark Invader en 26 Julio 2011, 22:28 pm
Si, es un seminario de lenguaje C, no nos permiten ni C++ ni C#.
Es más, nos hicieron hacer un trabajo final de manejos de .BMP y nos hicieron hacer todo por nuestra cuenta, nada de usar funciones predefinidas de BMP ni nada, todo manual...
Aprendí bastante, pero fue un dolor de cabeza importante, jaja...

Jaja me lo imagino  :xD


Título: Re: Problema con violación de segmento
Publicado por: naderST en 26 Julio 2011, 22:34 pm
Te recomiendo que leas mas sobre punteros, con respecto a #define fíjate que estas poniendo ';' al final y ahí no lleva ';'


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 26 Julio 2011, 22:47 pm
Si, justamente lo que mas me cuesta son las listas en C... En Pascal las manejo de diez, pero con C y el tema de los punteros me agarro un lindo pedalin...


Título: Re: Problema con violación de segmento
Publicado por: rir3760 en 27 Julio 2011, 02:49 am
En C la conversión explicita no es necesaria y no se recomienda, en este lenguaje el idioma (convención informal) para reservar memoria es:
Código
  1. p = malloc(N * sizeof *p);
Donde N es el numero de elementos.

En tus programas (me refiero a Triper0) sigues con el mismo error que ya te mencionaron: reservas memoria para "sizeof(algun_puntero)" cuando el tamaño debería indicar el tamaño del objeto apuntado. Por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define LONG_MAX_LINEA  1024
  5.  
  6. int main(void)
  7. {
  8.   char *p;
  9.  
  10.   if ((p = malloc(LONG_MAX_LINEA)) == NULL)
  11.      return EXIT_FAILURE;
  12.  
  13.   puts("Introduce una linea de texto:");
  14.   if (fgets(p, LONG_MAX_LINEA, stdin) == NULL)
  15.      return EXIT_FAILURE;
  16.  
  17.   printf("Linea: %s", p);
  18.   free(p);
  19.  
  20.   return EXIT_SUCCESS;
  21. }
En este caso no se requiere de "sizeof *p" ya que es igual a "sizeof(char)" y este siempre es igual a uno.

En cuanto al ultimo programa (para practicar con uniones) tiene varios errores, el principal que se utiliza la unión como si fuera una estructura. Aquí lo mejor es conseguir (y seguir) un buen libro. Recomendaciones sobre ellos en uno de los temas fijos.

Un saludo


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 27 Julio 2011, 04:09 am
En C la conversión explicita no es necesaria y no se recomienda, en este lenguaje el idioma (convención informal) para reservar memoria es:
Código
  1. p = malloc(N * sizeof *p);
Donde N es el numero de elementos.

En tus programas (me refiero a Triper0) sigues con el mismo error que ya te mencionaron: reservas memoria para "sizeof(algun_puntero)" cuando el tamaño debería indicar el tamaño del objeto apuntado. Por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define LONG_MAX_LINEA  1024
  5.  
  6. int main(void)
  7. {
  8.   char *p;
  9.  
  10.   if ((p = malloc(LONG_MAX_LINEA)) == NULL)
  11.      return EXIT_FAILURE;
  12.  
  13.   puts("Introduce una linea de texto:");
  14.   if (fgets(p, LONG_MAX_LINEA, stdin) == NULL)
  15.      return EXIT_FAILURE;
  16.  
  17.   printf("Linea: %s", p);
  18.   free(p);
  19.  
  20.   return EXIT_SUCCESS;
  21. }
En este caso no se requiere de "sizeof *p" ya que es igual a "sizeof(char)" y este siempre es igual a uno.

En cuanto al ultimo programa (para practicar con uniones) tiene varios errores, el principal que se utiliza la unión como si fuera una estructura. Aquí lo mejor es conseguir (y seguir) un buen libro. Recomendaciones sobre ellos en uno de los temas fijos.

Un saludo


Ese "N se refiere a número de elementos" cómo sería?... Por ejemplo, si yo tengo un puntero de tipo int, sería N=1
Y si tengo un char *nombre[10] sería N=10... ¿Así?

El tema de las uniones, seguramente tenga millones de errores, NUNCA use una unión, y justo vi un ejercicio sólo de unión, leí que era parecido a el struct pero no le encuentro la diferencia...
El libro que leí todo y seguí paso a paso, que fue uno de los que me recomendaron en la cátedra fue "C con ejemplos"...
Explica muy bien todo, pero no llega a cosas "muy avanzadas" como listas que es algo de lo cual necesito saber bien porque estoy seguro que en el parcial me van a tomar eso, además de obvio, para aprender más...

Desde ya muchísimas gracias también por el ejemplo y por todo ;)


Título: Re: Problema con violación de segmento
Publicado por: rir3760 en 27 Julio 2011, 04:36 am
Ese "N se refiere a número de elementos" cómo sería?... Por ejemplo, si yo tengo un puntero de tipo int, sería N=1
Y si tengo un char *nombre[10] sería N=10... ¿Así?
No.

El numero de elementos que piensas utilizar. Por ejemplo si necesitas espacio para una cantidad N de enteros (determinado en tiempo de ejecución) utilizas (sin validación para que sea mas sencillo):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.   int *p;
  7.   int num_elem;
  8.   int i;
  9.  
  10.   printf("Indica el numero de elementos: ");
  11.   fflush(stdout);
  12.   scanf("%d", &num_elem);
  13.  
  14.   /* Reserva de memoria */
  15.   p = malloc(num_elem * sizeof *p);
  16.  
  17.   /* Lectura de datos */
  18.   for (i = 0; i < num_elem; i++){
  19.      printf("p[%d] == ", i);
  20.      fflush(stdout);
  21.      scanf("%d", p + i); /* Equivalente a "&p[i]" */
  22.   }
  23.  
  24.   /* Algun proceso de datos ... */
  25.  
  26.   /* Liberacion de memoria y salida del programa */
  27.   free(p);
  28.   return EXIT_SUCCESS;
  29. }

Un saludo


Título: Re: Problema con violación de segmento
Publicado por: Triper0 en 27 Julio 2011, 05:26 am
No.

El numero de elementos que piensas utilizar. Por ejemplo si necesitas espacio para una cantidad N de enteros (determinado en tiempo de ejecución) utilizas (sin validación para que sea mas sencillo):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.   int *p;
  7.   int num_elem;
  8.   int i;
  9.  
  10.   printf("Indica el numero de elementos: ");
  11.   fflush(stdout);
  12.   scanf("%d", &num_elem);
  13.  
  14.   /* Reserva de memoria */
  15.   p = malloc(num_elem * sizeof *p);
  16.  
  17.   /* Lectura de datos */
  18.   for (i = 0; i < num_elem; i++){
  19.      printf("p[%d] == ", i);
  20.      fflush(stdout);
  21.      scanf("%d", p + i); /* Equivalente a "&p[i]" */
  22.   }
  23.  
  24.   /* Algun proceso de datos ... */
  25.  
  26.   /* Liberacion de memoria y salida del programa */
  27.   free(p);
  28.   return EXIT_SUCCESS;
  29. }

Un saludo

Ahahaha, fenómeno!!!...
Millón de gracias nuevamente  ;-)


Título: Re: Problema con violación de segmento
Publicado por: alesurf1989 en 8 Noviembre 2015, 21:34 pm
estoy igual que el amigp! soy un programador novato! tengo problemas con algun for! me sale el errror violacion de segmento core generado! se que el problema debe estar en algun for que se esta saliendo del espacio y esta tocando la memoria o algo asi fue que me explicaron y he dado vueltas y nada que he podido resolver!!!! gracias espero una respuesta!!!!!
 para la ayuda de un buen samaritano y programador!















#include <stdio.h>
#include <time.h>
//Bienvenido al juego tres en raya

void loop (char c[3][3]);
void Intro_Primera (char c[3][3]);
void tablero  (char c[3][3]); // tablero para mostrar en pantalla
void Intro_Yo (char c[3][3]); //turno del jugador o usuario
void Intro_IA (char c[3][3]); //turno aleatorio o computadora
int  ganador  (char c[3][3]); //funcion para determinar quuien gana

int main () {

    char c [3][3];
         
    loop (c);
   
   system ("pause");
   return 0;
   
}
   
void loop (char c [3][3]){
   int i, j;
   
   i = 0;
   
   Intro_Primera (c);
   tablero(c);
   
   do{
       system ("cls");
       tablero(c);
       
       if (i % 2 == 0) {
          Intro_Yo (c);
       }
       else {
             Intro_IA (c);
             }
             j = ganador (c);             
             i++;
   
   }while (i <= 9 && j == 2);
   
   if (j == 0){
     printf ("Muy Bien!! Has ganado!!\n\n");
     }
     else if (j == 1){
           printf ("ohhh noo!! Has perdido!!");
           }
           else{
                printf ("Has empatado!! Intentalo de nuevo!!");
     
   }
}

void Intro_Primera (char c[3][3]){
   int i, j;
   char aux;
   
   aux='1';
   
   for (i = 0; 1 < 3; i++){
       for (j = 0; j < 3; j++){
          c[j] = aux++;
       }
   }
}

void Intro_Yo(char c[3][3]){
  int i, j, k;
  char aux;
 
     
    do{
       do{
        printf ("Coloca una ficha:  ");
        fflush (stdin);
        scanf ("%c",&aux);
        }while (aux < '1' || aux > '9');
       
         k = 0;
       
      switch (aux){
         case '1': {
                 i = 0;
                 j = 0;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                      break;                 
                 }     
                 
         case '2': {
                 i = 0;
                 j = 1;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                     break;                 
                 }
         case '3': {
                 i = 0;
                 j = 2;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                     break;                 
                 }           
         case '4': {
                 i = 1;
                 j = 0;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                      break;                 
                 }   
         case '5': {
                 i = 1;
                 j = 1;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                     break;                 
                 }     
         case '6': {
                 i = 1;
                 j = 2;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                     break;                 
                 }     
         case '7': {
                 i = 2;
                 j = 0;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                      break;                 
                 }     
         case '8': {
                 i = 2;
                 j = 1;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                     break;                 
                 }     
         case '9': {
                 i = 2;
                 j = 2;
                    if (c[j] == 'X' || c[j] == 'O'){
                     k = 1;
                     printf ("la posicion esta ocupada! Intentalo con otro numero!!\n\n");
                 }
                      break;                 
                 }     
        }
    }while (k == 1);
   
    c[j] = 'X';
   
}

void Intro_IA (char c[3][3]){
     int i, j, k;
     
     
     srand (time(NULL));
     do{
         
    i = rand() % 3;
    j = rand() % 3;
    k = 0;
   
     if (c[j] == 'X' || c[j] == 'O'){
         k = 1;
         }
   }while (k == 1);
   
    c[j] = 'O';
}

void tablero (char c[3][3]){
  int i, j;
 
  for (i = 0; 1 < 3; i++){
       for ( j = 0; j < 3; j++){
          if (j < 2){
                printf (" %c  |",c[j]);
          }   
            else {
                  printf (" %c ",c[j]);
            }
       }     
       if (i < 2){
          printf ("\n-----------\n");       
       }
  }
  printf ("\n\n");


int ganador (char c[3][3]){
    if (c[0][0] == 'X' || c[0][0] == 'O'){
        if (c[0][0] == c[0][1] && c[0][0] == c[0][2]){
           if (c[0][0] == 'X'){
                     return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }
        if (c[0][0] == c[1][0] && c[0][0] == c[2][0]){
            if (c[0][0] == 'X'){
                 return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }       
    }
   
        if (c[1][1] == 'X' || c[1][1] == 'O'){
       if (c[1][1] == c[0][0] && c[1][1] == c[2][2]){
        if (c[1][1] == 'X'){
                 return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        } 
        if (c[1][1] == c[1][0] && c[1][1] == c[1][2]){
            if (c[1][1] == 'X'){
                 return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }     
             if (c[1][1] == c[2][0] && c[1][1] == c[0][2]){
                if (c[1][1] == 'X'){
                 return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }
          if (c[1][1] == c[0][1] && c[1][1] == c[2][1]){
            if (c[1][1] == 'X'){
                 return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }                   
    }
    if (c[2][2] == 'X' || c[2][2] == 'O'){
       if(c[2][2] == c[2][0] && c[2][2] == c[2][1]){
          if (c[2][2] == 'X'){
                    return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }                   
       if (c[2][2] == c[0][2] && c[2][2] == c[1][2]){
          if (c[2][2] == 'X'){
                     return 0; //ha ganado
               }
               else{
                     return 1; // ha perdido
            }         
        }   
   }
   return 2;   
}