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

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


  Mostrar Temas
Páginas: [1]
1  Programación / Programación C/C++ / Cuando fgets ensucia el buffer :S en: 21 Mayo 2010, 00:57 am
Hola a todos!!

bien recien haciendo unas pequeñas pruebas me di cuenta que en ciertas situaciones fgets con stdin... me ensucia el buffer mas especificamente cuando agrego mas caracteres de los que espera doy un ejemplo

Código
  1.  
  2. #include <stdio.h>
  3.  
  4. int main(int argc, char **argv)
  5. {
  6. char cad[5];
  7.  
  8.  
  9. fgets (cad, sizeof(cad), stdin); //si ingresamos "hola mundo"
  10. puts (cad);                           // imprime "hola"
  11. fgets (cad, sizeof(cad), stdin);// se lo saltea (buffer sucio)
  12. puts (cad);                          // imprime "mun"
  13.  
  14.  
  15. return 0;
  16.  
  17. }
  18.  
  19.  
  20.  


obviamente se puede solucionar haciendo que cad sea mas "grande" como de 120 caracteres, pero quisiera saber alguna manera de no recurrir a eso sino. evitar que el buffer quede sucio....
nada de fflush

EDITADO:
Bueno recién probando encontré que haciendo esto funciona :

Código
  1. setbuf(stdin,NULL);  
  2.  
 
aunque me vuele a que es algo parecido a fflush


espero respuestas, gracias!!!    



2  Programación / Programación C/C++ / [Aporte] Archivos Binarios en C en: 19 Mayo 2010, 23:38 pm
consiste en dos programas  en el primero se hacen la entrada de datos y en el segundo se realizan modificaciones...
mucha ganas de explicarlo no tengo  :P jeje de ultima si no se entiende un joroca me explico con mas detalle mas tarde..

arch.h

Código
  1.  
  2.  
  3. #include <stdio.h>
  4.  
  5. typedef struct FECHA{
  6.  
  7. int d, m, a;
  8. }fecha;
  9.  
  10. typedef struct TIEMPO{
  11.  
  12. int h, m, s;
  13.  
  14. }tiempo;
  15.  
  16. struct atleta{
  17.  
  18. char nombre[30];
  19. fecha f;
  20. char sx; //sexo
  21. char cat; //categoria
  22. tiempo t;
  23. unsigned int dorsal;
  24. unsigned short puesto;
  25.  
  26. };
  27.  
  28. typedef struct atleta atle;
  29. #define desplz(n) (n-1) *sizeof (atle)
  30.  
  31.  

archivo de entrada.c

Código
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #include "atleta.h"
  9. #define randomize (srand(time(NULL)))
  10. #define random(num) (rand()%(num))
  11.  
  12. void inicializar (FILE* pf);
  13. void igresar_A (FILE* pf, atle* at);
  14. unsigned numdorsal (char s, char cat, FILE * pf);
  15.  
  16.  
  17.  
  18. int main(int argc, char** argv)
  19. {
  20. FILE *pf;
  21. atle atletas;
  22. char *archivo = "Carrera.dat";
  23. randomize;
  24.  
  25. if ((pf= fopen( archivo, "wb+")) == NULL)
  26. {
  27. printf ("\n Error al abrir archivo ");
  28. return -1;
  29. }
  30.  
  31. inicializar(pf);
  32.  
  33. igresar_A(pf, &atletas);
  34. do
  35. {
  36. fseek(pf, desplz(atletas.dorsal), 0);
  37. fwrite (&atletas, sizeof(atletas),1,pf);
  38. igresar_A(pf, &atletas);
  39.  
  40. }while (strcmp (atletas.nombre, "FIN"));
  41.  
  42.  
  43.  
  44. fclose (pf);
  45.  
  46.  
  47. return 0;
  48. }
  49.  
  50. void inicializar (FILE* pf)
  51. {
  52. int i;
  53. atle a;
  54.  
  55. a.nombre[0] = '\0';
  56.  
  57. for (i=0; i<1000; i++)
  58. fwrite(&a, sizeof(atle), 1, pf);
  59.  
  60.  
  61. }
  62.  
  63. void igresar_A (FILE* pf, atle* at)
  64. {
  65. char buf[30];
  66. int n;
  67.  
  68. buf[0]='\0';
  69. printf ("Nombre    ");
  70. fgets (buf, 30, stdin);
  71. n = strlen (buf);
  72. if (buf[n] == '\n');
  73. buf[n] = '\0';
  74.  
  75. sscanf(buf,"%s", at->nombre);
  76. if (strcmp (at->nombre, "FIN"))
  77. {
  78. printf ("ingrese la fecha de naciemiento (dd mm aaaa)");
  79. buf[0]='\0';
  80. fgets (buf, 30, stdin);
  81. sscanf (buf, "%d %d %d", &at->f.d, &at->f.m, &at->f.a);
  82. if (at->f.a < 1954)
  83. at->cat = 'V';
  84. else
  85. at->cat = 'S';
  86.  
  87. printf ("Sexo (M/F)");
  88. fgets (buf, 3, stdin);
  89. sscanf (buf, "%c", &at->sx);
  90.  
  91. at->sx = (char) toupper(at->sx);
  92.  
  93.  
  94. at->t.h = 0;
  95. at->t.m = 0;
  96. at->t.s = 0;
  97.  
  98. at->dorsal = numdorsal(at->sx, at->cat, pf);
  99. printf ("%d", at->dorsal);
  100.  
  101. }
  102. }
  103.  
  104. unsigned numdorsal (char s, char cat, FILE * pf)
  105.  
  106. {
  107. unsigned base, tope, d;
  108. atle at;
  109.  
  110. if (s == 'M' && cat=='V')
  111. {
  112. base = 251;
  113. tope = 500;
  114. }
  115. else if (s == 'M' && cat == 'S')
  116. {
  117. base = 501;
  118. tope = 1000;
  119. }
  120. else if (s == 'F' && cat == 'V')
  121. {
  122. base = 51;
  123. tope = 100;
  124. }
  125. else if (s == 'F' && cat == 'S')
  126. {
  127. base = 101;
  128. tope = 200;
  129. }
  130.  
  131. d = (unsigned) random(tope+1-base)+base;
  132. fseek(pf, desplz(d),0);
  133. fread(&at,sizeof(atle),1,pf);
  134. if (!(*at.nombre))
  135. return d;
  136. else
  137. return numdorsal(s, cat, pf);
  138.  
  139. }
  140.  
  141.  


archivo de entrada a tiempos de atletas.c


Código
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #include "atleta.h"
  9.  
  10.  
  11. void muestraDatos (atle at);
  12. void dorsalesjuego (FILE* pf );
  13.  
  14.  
  15. int main(int argc, char** argv)
  16. {
  17. FILE * pf;
  18. atle atletas;
  19.  
  20. unsigned dorsal1;
  21. char dor[20], *archivo = "Carrera.dat";
  22.  
  23.  
  24. if ((pf = fopen (archivo, "rb+")) == NULL)
  25. {
  26. printf ("Error al abrir archivo");
  27. return -1;
  28. }
  29.  
  30. dorsalesjuego(pf);
  31.  
  32. printf ("Escriba el numero de dorsal: ");
  33. fgets (dor, 5, stdin);
  34. sscanf (dor, "%u", &dorsal1);
  35. while (dorsal1)
  36. {
  37. fseek(pf,desplz(dorsal1), 0);
  38. fread(&atletas, sizeof(atletas),1,pf);
  39.  
  40. if (*atletas.nombre)
  41. {
  42.  
  43. muestraDatos(atletas);
  44. printf ("\n Tiempo realizado en minutos y segundos: ");
  45.    fgets (dor, 15, stdin);
  46.    sscanf (dor, "%d %d", &atletas.t.m, &atletas.t.s);
  47.    fseek(pf,desplz(dorsal1), 0);
  48.    fwrite(&atletas, sizeof(atle),1,pf);
  49. }
  50. else
  51. printf ("Dorsal no encontrado, vuelva a intentar\n");
  52.  
  53. fgets (dor, 5, stdin);
  54. sscanf (dor, "%u", &dorsal1);
  55.  
  56. }
  57.  
  58.  
  59. fclose(pf);
  60.  
  61.  
  62.  
  63.  
  64. return 0;
  65. }
  66.  
  67.  
  68. void muestraDatos (atle at)
  69.  
  70. {
  71. printf ("Nombre : %s\n", at.nombre);
  72. printf ("Fecha de naciemiento : %d-%d-%d\n", at.f.d, at.f.m, at.f.a);
  73. printf ("Categoria : %c\nDorsal: %u\n", at.cat, at.dorsal);
  74. if (at.t.m > 0)
  75. printf ("\ntiempo de carrera : %d Min %d Seg", at.t.m, at.t.s );
  76.  
  77.  
  78.  
  79. }
  80.  
  81.  
  82. void dorsalesjuego (FILE* pf )
  83.  
  84. {
  85. atle at;
  86.  
  87. printf ("jugadores en jeugo \n");
  88.  
  89. while ( !feof(pf) )
  90. {
  91. fread (&at, sizeof(atle),1,pf);
  92. if (*at.nombre)
  93. printf ("numero de dorsal %d\n", at.dorsal);
  94. }
  95.  
  96.  
  97. }
  98.  



eso fue todo saludos

 
  
3  Programación / Programación C/C++ / ok en: 19 Mayo 2010, 03:16 am
pregunta que hice hace dias en el lugar equivocado, la cual ya tengo clara 
4  Programación / Programación C/C++ / el porque del scanf no es recomendable en: 16 Mayo 2010, 20:53 pm
Hola Gente!!

BUENO ESTO ES UNA EXPLICACIÓN DE PORQUE AVECES EL SCANF SE COMPORTA DE MANERA EXTRAÑA. ESPERO QUE SE ENTIENDA,  

voy explico porque el uso de scanf no es recomendable..
para empezar es un error decir que un programa lee del teclado en verdad lo que hace es leer de un area de memoria llamado "buffer de teclado" (no siempre es así, esto se puede manipular mediante la función  setvbuf y el modo _IOFBF, que especifica que lea hasta que el buffer esté lleno.) y el buffer del teclado es "buffer de linea" esto quiere decir que los datos que provienen del teclado se insertan linea por linea y no caracter a caracter . Es por eso que cuando leemos de ahí, por más que ingresemos muchos caracteres, hasta que no ingresamos el fin de línea (enter) el programa no lee nada y se queda trabado esperando que haya algo en el buffer.

si el buffer no está vacío, sí o sí hay al menos un fin de línea;
el buffer siempre tiene un carácter de fin de línea al final.

El gran problema con scanf es que no siempre leerá el fin de linea lo que nos lleva a que el buffer quede con basura, osea con caracteres no leídos los cuales la próxima vez que invoquemos a scanf los leerá e intentara limpiar el buffer ocasionando un salto de linea e impediendonos ingresar el dato requerido.  de mas esta decir que esto podría causar algunos problemas al programador.
scanf solo lee hasta que encuentre el formato que le especificamos, esto conlleva a otro gran problema ya que si nosotros le decimos que lea un entero (%i") y se le ingresan 2 enteros separados por un espacio scanf solo leerá hasta encontrar el formato especificado dejando al buffer sucio con ese entero de mas.
Otro problema que tenemos es que no hace casi ningún tipo de chequeo a la hora de verificar los datos ingresados si se le indica que se ingresara un entero y el usuario ingresa una letra esté hace una conversión a entero lo cual genera un problema.


en el siguiente segmento de programa intenten lo siguiente cuando les piede ingresar los datos pongan algo así como "50 10" (sin las comillas) y veran como el buffer quedara  sucio  con con el entero 10 entonces cuando se llama de nuevo a scanf "asimila" que 10 es lo que se ingreso y por eso no nos deja ingresar el dato e imprime el nuevo valor de i       

Código
  1.  
  2. nt main(int argc, char** argv)
  3. {
  4. int i;
  5.  
  6. scanf ("%d", &i );
  7. printf ("%d\n",i);
  8. scanf ("%d", &i );
  9. printf ("%d",i);
  10.  
  11.  
  12. return 0;
  13.  
  14.  
  15. }
  16.  
  17.  



por estas razones no es recomendable usarlo siempre se puede suplantar con algo que no ensucie el buffer para eso utilsaremos sscanf y fgets :

 
Código
  1.  
  2. #include <stdio.h>
  3.  
  4.  
  5.  
  6. int main()
  7. {
  8.   char nombre[20]="", entrada[81]="";
  9.   unsigned int edad=0;
  10.  
  11.   printf( "Escriba su nombre y edad, separados por un espacio:\n" );
  12.   fgets(entrada, 20, stdin ); //llenamos el buffer reservando 20 caracteres y stdin es la entrada standar
  13.   sscanf( entrada, "%s %u", nombre, &edad ); //con sscanf introducimos lo que tenemos en el buffer tanto en nombre como en edad    
  14.  
  15.   printf( "Has escrito: %s\n", entrada ); //lo que tenemos en el buffer
  16.   printf( "Nombre: %s. Edad: %d\n", nombre, edad ); //
  17.  
  18.  
 

El uso de fgets puede traer inconvenientes menores los cuales son  solucionables no voy a profundizar en este tema ya que ya hay un pequeño post que habla del mismo

bueno eso es todo...

Saludos Cordiales
5  Programación / Programación C/C++ / [Solucionado]Problema con archivo en: 15 Mayo 2010, 06:27 am
Hola gente bueno les cuento que tengo un incomeniente con un programa que genera un archivo de texto y pone datos en él hasta ahí va perfecto
el problema es cunado quiero tomar esos archivos e imprimirlos en pantalla
no se si estoy tomando mal los datos del archivo o estoy ingresando mal los datos en el archivo, pero el tema es que me termina imprimiendo dos veces la ultima linea del archivo...


Bueno al final era un problema con como imprimía en pantalla lo que havia en el archivo de texto   

Código:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>


typedef struct {
char *nm;
int dia;
int ms;
int aa;
char mes[11];
}Persona;



void entrada (Persona* p);
char* mes_asci (int n);


int main(int argc, char** argv)
{
FILE *pff;
char fn[] = "Personas.DAT";
char buf[121];

if ( (pff = fopen(fn,"a+t")) == NULL )
{
puts ("Error al abrir archivo");
exit (-1);
}

//while (!feof(pff))
        while (fgets (buf,121,pff))
       {

printf ("%s \n\n",buf);
 
}



Persona pt;

entrada (&pt);
fprintf(pff,"%s %d-%d-%d %s\n", pt.nm, pt.dia, pt.ms, pt.aa, pt.mes);

fclose(pff);
return 0;
}



void entrada (Persona * p)
{
char bf[80];

printf ("Escriba el nombre: ");
fgets (bf,80,stdin);
if (bf[strlen(bf) - 1] == '\n' )
bf[strlen(bf)] = '\0';
p->nm = (char*) malloc ((strlen (bf) + 1) * sizeof(char));
strcpy (p->nm, bf);
do
{
printf ("introduzca dia mes año (dd mm aaaa) : ");
fgets (bf, 80, stdin);
if (bf[strlen(bf) - 1] == '\n' )
bf[strlen(bf)] = '\0';
sscanf (bf,"%d %d %d%*c", &p->dia, &p->ms, &p->aa );
printf ("\n %s\n", mes_asci(p->ms));

} while  ( ( mes_asci(p->ms) == "Mes eroneo") || (p->dia > 31 || p->dia < 1 ) );

strcpy(p->mes, mes_asci(p->ms));

}

char* mes_asci (int n)

{
static char *mes[12] = {
"Enero", "Febrero", "Marzo", "Abril",
"Mayo", "Junio", "Julio", "Agosto", "Septiembre",
"Octubre", "Noviembre", "Diciembre" };

 
if (n >= 1 && n <= 12)
return mes[n-1];
else
return "Mes eroneo";


}



 

 
6  Programación / Programación C/C++ / truncar teclado! en: 13 Mayo 2010, 03:45 am
Hola a todos!!

bueno tengo una pequeña duda estaba pensando en que si hay alguna manera de poder truncar o bloquear las teclas cuando se pide que se igresen datos, me explico, supongamos que se pide que se ingrese una cadena y a la hora de teclear por ejemplo la etra "n", nisiquiera se imprima en pantalla cuando la presiono... se que deve haber  alguna manera con directivas o algo asi
yo me imagino que puede ser revisando primero las letras que uno presiona con una funcion como getchar o algo asi pero no se me ocurre del todo como implementarlo
bueno espero que puedan ayudarme

os dejo Saludos.......
  
7  Programación / Programación C/C++ / Problemas!!... matriz Dinamicos en: 10 Mayo 2010, 06:27 am
Hola gente!!!

bueno les cuento que estoy ante un gran dilema esto es asi:

mediante una matriz estatica de enteros de 20 x 20 hay que generar dinamicamente otra matriz cuyos elementos son todos aquellos que son unicos en la matriz estatica de 20 x 20, es decir si en la matriz estatica tenemos:
 pos[0][0]=1 
 pos[0][1]=1
 pos[0][2]=23

en la dinamica tendremos pos[0][0]=23

ya que 23 es unico en la matriz


el algoritmo responde bien hace exactamente eso pero me quedo muy confuso si alguien purde sugerir alguna manera de arreglarlo o de encararlo por otro lado seria grandioso !!

Código
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6.  
  7. void gen_matriz (int** nuevo, int matriz[20] [20])
  8.  
  9. {
  10. int j, k, y;
  11. int dup;
  12. int num_elem[20];
  13.  
  14. nuevo = (int**) calloc(20, sizeof(int*));
  15.  
  16.  
  17. for (y = 0; y < 20; y++)
  18. {
  19. num_elem[y] = 0;
  20.  
  21. for (k = 0; k < 20; k++)
  22. {
  23. dup = 0;
  24. j = 0;
  25. while ((j < 20) && !dup)
  26. {
  27.  
  28.  if (k != j)
  29.  {
  30. dup = matriz[y][k] == matriz[y][j];
  31. printf ("y=%i %i %i\n",y, j, dup);
  32.  }
  33.  j++;
  34. }
  35. printf ("dup %i\n", dup);
  36. if (!dup)
  37. {
  38.  
  39. num_elem[y]++;
  40. if (nuevo[y] == NULL)
  41.  nuevo[y] = (int*) malloc(sizeof (int));
  42. else
  43.  nuevo[y] = (int*) realloc(nuevo[y], num_elem[y] * sizeof (int));
  44.  
  45. int indice = num_elem[y] - 1;  
  46. nuevo[y][indice] = matriz[y][k];
  47. printf (" posicion %i %i : %i\n", y, k, nuevo [y] [indice]);
  48.  
  49. }
  50. }
  51.  
  52. }
  53.  
  54. for(y = 0; y < 20; y++)
  55. for(k = 0; k < num_elem[y]; k++)
  56. printf("nuevo[%i][%i] = %i\n", y, k, nuevo[y][k]);
  57. }
  58.  
  59.  
   
esta un poco desprolijo espero que se entienda

espero que me puedan ayudar saludos!!!

Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines