sustituir scanf

Iniciado por m@o_614, 12 Octubre 2013, 04:29 AM

0 Miembros y 1 Visitante están viendo este tema.

m@o_614

Saludos

Tengo el siguiente codigo en el que le ingresas datos a una estructura x, el programa compila correctamente pero tengo una duda, tengo entendido que cuando alternas una funcion como fgets() y scanf() te da problemas, y para esto le puse un ciclo while con un getchar(). Pero queria saber si podia sustituir el scanf por otra funcion que no me provoque basura en el buffer, para asi no tener que ponerle el while(getchar()!= '\n')

#include <stdio.h>
#include <stdlib.h>
#define TAM 20
#define MAX 10
typedef struct datos
{
   char nombre[TAM];
   int edad;
   char ciudad_residencia[TAM];
}Persona;

void entrada(Persona *p);

int main()
{
   Persona p;
   int i;
   for(i = 0;i < 10;i++)
      entrada(&p);
   return 0;
}

void entrada(Persona *p)
{
   printf("Dame nombre:\n");
   fgets(p->nombre,TAM,stdin);
   printf("Dame edad:\n");
   while(getchar()!='\n')
   scanf("%d",&p->edad);
   printf("Dame ciudad de residencia:\n");
   fgets(p->ciudad_residencia,TAM,stdin);
}


gracias

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

m@o_614

Saludos Eternal Idol, por lo que he entendido la funcion sscanf obtiene la entrada de un arreglo y no de un stream, entonces si yo quisiera ponerle un stdin para indicarle que va a tomar la entrada de lo que le ingrese por el teclado me va a dar error, que puedo hacer en este caso?

de antemano gracias

Eternal Idol

Para eso se llama primero a fgets con stdin, fijate en el enlace que deje antes.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

m@o_614

muchas gracias Eternal Idol ya cheque el enlace que dejaste, y ya pude hacer el codigo que me tiene que ingresar datos de una estructura en un archivo, cerrarlo y despues que me imprima en pantalla los datos que se habian guardado, pero tengo otra duda, cada vez que utilizas fgets() es necesario quitarle el salto de linea '\n', se recomienda hacer eso?? y tambien en el sscanf si quiero que lo que me ingrese sea un entero no se desperdicia espacio en el array que le puse asi:

void entrada(Persona *p)
{
    char cad[10];
    printf("Dame nombre:\n");
    fgets(p->nombre,MAX,stdin);
    printf("Dame edad:\n");
    fgets(cad,10,stdin);// aqui tiene una array de 10 elementos pero solo ocupo un int
    sscanf(cad,"%d",&p->edad);
}


aqui esta el codigo completo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
/*
   Crear un "struct" que almacene los siguientes datos de una persona: nombre, edad, ciudad de residencia.
   Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado "gente.dat", cerrar el fichero,
   volverlo a abrir para lectura y mostrar los datos que se habían guardado.
*/
typedef struct datos
{
    char nombre[MAX];
    int edad;
    char ciudad_residencia[MAX];
}Persona;

void entrada(Persona *p);
void mostrar(FILE *ap);

int main()
{
    FILE *fd,*ap;
    Persona p;
    if((fd = fopen("F:\\gente.txt","w"))!= NULL)
    {
        entrada(&p);
        fprintf(fd,"%s\n",p.nombre);
        fprintf(fd,"%d\n",p.edad);
        fprintf(fd,"%s\n",p.ciudad_residencia);
        fclose(fd);
        if((ap = fopen("F:\\gente.txt","r"))!= NULL);
           mostrar(ap);
    }
    else
       printf("No se pudo crear archivo");
    return 0;
}

void entrada(Persona *p)
{
    char cad[10];
    printf("Dame nombre:\n");
    fgets(p->nombre,MAX,stdin);
    printf("Dame edad:\n");
    fgets(cad,10,stdin);
    sscanf(cad,"%d",&p->edad);
    printf("Dame ciudad de residencia:\n");
    fgets(p->ciudad_residencia,MAX,stdin);
    system("cls");
}

void mostrar(FILE *ap)
{
    int car;
    while((car = fgetc(ap))!= EOF)
       printf("%c",car);
}

Eternal Idol

Cita de: m@o_614 en 15 Octubre 2013, 22:28 PMmuchas gracias Eternal Idol ya cheque el enlace que dejaste, y ya pude hacer el codigo que me tiene que ingresar datos de una estructura en un archivo, cerrarlo y despues que me imprima en pantalla los datos que se habian guardado, pero tengo otra duda, cada vez que utilizas fgets() es necesario quitarle el salto de linea '\n', se recomienda hacer eso?? y tambien en el sscanf si quiero que lo que me ingrese sea un entero no se desperdicia espacio en el array que le puse asi:

De nadas. Partiendo de la base de que esta el salto de linea (dependera del tamaño que le pases a fgets y lo que escriba el usuario) si lo que queres guardar no es una linea en si misma entonces tiene sentido sacarlo. cad solo tiene como ambito entrada, cuando la funcion retorna esos caracteres en la pila vuelven a estar disponibles.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

m@o_614

una ultima pregunta, si le quiero hacer una modificacion al codigo y en vez de que me guarde los datos de la estructura en el archivo con fprintf quiero que lo haga con fwrite, ya no funciona como lo hacia con fprintf ahora me imprime basura, por que sucede esto??

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
/*
   Crear un "struct" que almacene los siguientes datos de una persona: nombre, edad, ciudad de residencia.
   Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado "gente.dat", cerrar el fichero,
   volverlo a abrir para lectura y mostrar los datos que se habían guardado.
*/
typedef struct datos
{
    char nombre[MAX];
    int edad;
    char ciudad_residencia[MAX];
}Persona;

void entrada(Persona *p);
void mostrar(FILE *ap);

int main()
{
    FILE *fd,*ap;
    Persona p;
    if((fd = fopen("F:\\gente.txt","w"))!= NULL)
    {
        entrada(&p);
        fwrite(&p,sizeof(Persona),1,fd);
        fclose(fd);
        if((ap = fopen("F:\\gente.txt","r"))!= NULL);
           mostrar(ap);
    }
    else
       printf("No se pudo crear archivo");
    return 0;
}

void entrada(Persona *p)
{
    char cad[10];
    printf("Dame nombre:\n");
    fgets(p->nombre,MAX,stdin);
    printf("Dame edad:\n");
    fgets(cad,10,stdin);
    sscanf(cad,"%d",&p->edad);
    printf("Dame ciudad de residencia:\n");
    fgets(p->ciudad_residencia,MAX,stdin);
    system("cls");
}

void mostrar(FILE *ap)
{
    int car;
    while((car = fgetc(ap))!= EOF)
       printf("%c",car);
}


Eternal Idol

fwrite hace exactamente lo que vos le decis, ahi estas pasandole sizeof(Persona) como tamaño y eso incluye TODOS los bytes de las cadenas, aunque estas esten terminadas antes ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

m@o_614

ya entendi en donde estaba el error, sizeof(Persona) es igual a 44 porque toma las elementos de la struct completos, otra duda, estaba leyendo en una pagina de internet y me decia que cuando estoy guardando estructuras en un archivo de texto tengo que hacerlo campo por campo, o sea que tendria que usar 3 fwrites() y cuando estoy abriendo el archivo en binario puedo hacerlo todo en un solo paso, si es asi o no?

gracias de nuevo

Eternal Idol

Si inicializas todo a 0 (asi por ejemplo se sabe donde termina la cadena) y no te importa escribir mas bytes de los necesarios podes escribir la estructura entera.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón