|
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 #include <stdio.h> int main(int argc, char **argv) { char cad[5]; fgets (cad , sizeof(cad ), stdin ); //si ingresamos "hola mundo" puts (cad ); // imprime "hola" fgets (cad , sizeof(cad ), stdin );// se lo saltea (buffer sucio) puts (cad ); // imprime "mun" return 0; }
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 fflushEDITADO: Bueno recién probando encontré que haciendo esto funciona :
aunque me vuele a que es algo parecido a fflushespero 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 jeje de ultima si no se entiende un joroca me explico con mas detalle mas tarde.. arch.h #include <stdio.h> typedef struct FECHA{ int d, m, a; }fecha; typedef struct TIEMPO{ int h, m, s; }tiempo; struct atleta{ char nombre[30]; fecha f; char sx; //sexo char cat; //categoria tiempo t; unsigned int dorsal; unsigned short puesto; }; typedef struct atleta atle; #define desplz(n) (n-1) *sizeof (atle)
archivo de entrada.c #include <stdio.h> #include <time.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include "atleta.h" #define randomize (srand(time(NULL))) #define random(num) (rand()%(num)) void inicializar (FILE* pf); void igresar_A (FILE* pf, atle* at); unsigned numdorsal (char s, char cat, FILE * pf); int main(int argc, char** argv) { FILE *pf; atle atletas; char *archivo = "Carrera.dat"; randomize; if ((pf = fopen( archivo , "wb+")) == NULL ) { printf ("\n Error al abrir archivo "); return -1; } inicializar(pf); igresar_A(pf, &atletas); do { fseek(pf , desplz (atletas. dorsal), 0); fwrite (&atletas , sizeof(atletas ),1,pf ); igresar_A(pf, &atletas); }while (strcmp (atletas. nombre, "FIN")); return 0; } void inicializar (FILE* pf) { int i; atle a; a.nombre[0] = '\0'; for (i=0; i<1000; i++) fwrite(&a , sizeof(atle ), 1, pf ); } void igresar_A (FILE* pf, atle* at) { char buf[30]; int n; buf[0]='\0'; if (buf[n] == '\n'); buf[n] = '\0'; if (strcmp (at ->nombre , "FIN")) { printf ("ingrese la fecha de naciemiento (dd mm aaaa)"); buf[0]='\0'; sscanf (buf , "%d %d %d", &at ->f. d, &at ->f. m, &at ->f. a); if (at->f.a < 1954) at->cat = 'V'; else at->cat = 'S'; at->t.h = 0; at->t.m = 0; at->t.s = 0; at->dorsal = numdorsal(at->sx, at->cat, pf); } } unsigned numdorsal (char s, char cat, FILE * pf) { unsigned base, tope, d; atle at; if (s == 'M' && cat=='V') { base = 251; tope = 500; } else if (s == 'M' && cat == 'S') { base = 501; tope = 1000; } else if (s == 'F' && cat == 'V') { base = 51; tope = 100; } else if (s == 'F' && cat == 'S') { base = 101; tope = 200; } d = (unsigned) random(tope+1-base)+base; fread(&at ,sizeof(atle ),1,pf ); if (!(*at.nombre)) return d; else return numdorsal(s, cat, pf); }
archivo de entrada a tiempos de atletas.c #include <stdio.h> #include <time.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include "atleta.h" void muestraDatos (atle at); void dorsalesjuego (FILE* pf ); int main(int argc, char** argv) { FILE * pf; atle atletas; unsigned dorsal1; char dor[20], *archivo = "Carrera.dat"; if ((pf = fopen (archivo , "rb+")) == NULL ) { printf ("Error al abrir archivo"); return -1; } dorsalesjuego(pf); printf ("Escriba el numero de dorsal: "); while (dorsal1) { fseek(pf ,desplz (dorsal1 ), 0); fread(&atletas , sizeof(atletas ),1,pf ); if (*atletas.nombre) { muestraDatos(atletas); printf ("\n Tiempo realizado en minutos y segundos: "); sscanf (dor , "%d %d", &atletas. t. m, &atletas. t. s); fseek(pf ,desplz (dorsal1 ), 0); fwrite(&atletas , sizeof(atle ),1,pf ); } else printf ("Dorsal no encontrado, vuelva a intentar\n"); } return 0; } void muestraDatos (atle at) { printf ("Nombre : %s\n", at. nombre); printf ("Fecha de naciemiento : %d-%d-%d\n", at. f. d, at. f. m, at. f. a); printf ("Categoria : %c\nDorsal: %u\n", at. cat, at. dorsal); if (at.t.m > 0) printf ("\ntiempo de carrera : %d Min %d Seg", at. t. m, at. t. s ); } void dorsalesjuego (FILE* pf ) { atle at; printf ("jugadores en jeugo \n"); { fread (&at , sizeof(atle ),1,pf ); if (*at.nombre) printf ("numero de dorsal %d\n", at. dorsal); } }
eso fue todo saludos
|
|
|
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 nt main(int argc, char** argv) { int i; return 0; }
por estas razones no es recomendable usarlo siempre se puede suplantar con algo que no ensucie el buffer para eso utilsaremos sscanf y fgets : #include <stdio.h> int main() { char nombre[20]="", entrada[81]=""; unsigned int edad=0; printf( "Escriba su nombre y edad, separados por un espacio:\n" ); fgets(entrada , 20, stdin ); //llenamos el buffer reservando 20 caracteres y stdin es la entrada standar sscanf( entrada , "%s %u", nombre , &edad ); //con sscanf introducimos lo que tenemos en el buffer tanto en nombre como en edad printf( "Has escrito: %s\n", entrada ); //lo que tenemos en el buffer printf( "Nombre: %s. Edad: %d\n", nombre , edad ); //
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
#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 !! #include <stdio.h> #include <stdlib.h> #include <ctype.h> void gen_matriz (int** nuevo, int matriz[20] [20]) { int j, k, y; int dup; int num_elem[20]; nuevo = (int**) calloc(20, sizeof(int*)); for (y = 0; y < 20; y++) { num_elem[y] = 0; for (k = 0; k < 20; k++) { dup = 0; j = 0; while ((j < 20) && !dup) { if (k != j) { dup = matriz[y][k] == matriz[y][j]; printf ("y=%i %i %i\n",y , j , dup ); } j++; } if (!dup) { num_elem[y]++; if (nuevo[y] == NULL) nuevo [y ] = (int*) malloc(sizeof (int)); else nuevo [y ] = (int*) realloc(nuevo [y ], num_elem [y ] * sizeof (int)); int indice = num_elem[y] - 1; nuevo[y][indice] = matriz[y][k]; printf (" posicion %i %i : %i\n", y , k , nuevo [y ] [indice ]); } } } for(y = 0; y < 20; y++) for(k = 0; k < num_elem[y]; k++) printf("nuevo[%i][%i] = %i\n", y , k , nuevo [y ][k ]); }
esta un poco desprolijo espero que se entienda espero que me puedan ayudar saludos!!!
|
|
|
|
|
|
|