After I formatted the \"direccion\"\'s scanf in function \"leerdatos\", it skip the \"nro_corredor\" in the second \'for\' loop.
I\'ve already read the related quest
One other issue you are faced with is the need to flush the input buffer (stdin) after calling scanf
. As chux noted, scanf
does not consume the newline '\n'
leaving it in the input buffer to be read as the next character. It is always good to flush the input buffer after each use of scanf
, especially when scanf
is called multiple times. A simple way to flush the input buffer is:
int c = 0; /* test int for getchar */
...
scanf("%d",&cp);
do { c=getchar(); } while ( c != '\n'); /* flush input buffer */
Note: fflushf
does not clear characters remaining in stdin
.
Incorrect usage of scanf()
// scanf(" %s\n", ...
scanf("%s", ...
A white-space like '\n'
after the "%s"
directs scanf()
to look for white-space until a non-white space follows. That non-white-space is put back into stdin
. This likely means OP had to enter 2 Enter for the 4th input.
Should always check the scanf()
return value to see if it is as expected.
// scanf("%d",&participante.nro_corredor);
if (scanf("%d",&participante.nro_corredor) != 1) Handle_Error();
Putting a space before "%s"
or "%d"
in scanf()
make no difference. These specifiers will consume optional white space even without a leading " "
.
Recommend to use fgets()
to read user input (which is evil) and then parse with sscanf()
, strtok()
, strtol()
, etc.
Note: except inside a scanset "%[...]"
, white-space like ' '
, '\t'
, '\n'
, and others each perform the same: They consume any number of white-space. That '\n'
in scanf(" %s\n",...
does not scan for 1 '\n'
. It scans for any number of any white-space. It will keep scanning white-space, including multiple Enters until EOF or a non-whitespace is entered. That non-white-space is then put back into stdin
as the next `char to be read.
#include <stdio.h>
struct s_tiempo
{
int minutos;
int segundos;
};
struct carrera
{
int nro_corredor; // guarda nro de corredor
struct s_tiempo tiempo; // guarda el tiempo que tardo el corredor
};
struct datos
{
int nro_corredor; // guarda nro de corredor
char apellido[20];
char nombres[20];
char direccion[30];
};
bool leerdatos( struct datos *); //declaro la funcion leer
int main (void)
{
int cp; //cantidad de participantes.
printf("Ingrese la cantidad de participantes: ");
if( 1 != scanf(" %d",&cp) )
{
perror( "failed getting participantes using scanf()");
return( 1 );
}
// implied else
struct datos corredor[cp];
struct carrera carreras[cp]; // should get compiler warning due to this not being used
printf("A continuacion, ingrese los datos de los corredores: \n");
for(int i=0;i<cp;i++)
{
if( !leerdatos( &corredor[i]) ) { return( 1 ); }
}
return( 0 );
}
bool leerdatos(struct datos* participante)
{
printf("\nIngrese el numero de corredor: ");
if( 1 != scanf(" %d",&participante.nro_corredor) )
{
perror( "failed getting numer de corredor using scanf()");
return( false );
}
// implied else
printf("\nIngrese el apellido:\n");
if( 1 != scanf(" %s",participante.apellido) )
{
perror( "failed getting apellido using scanf()");
return( false );
}
// implied else
printf("\nIngrese los nombres:\n");
if( 1 != scanf("%s",participante.nombres) )
{
perror( "failed getting nombres using scanf()");
return( false );
}
// implied else
printf("\nIngrese la direccion:\n");
if( 1 != scanf(" %s\n",participante.direccion) )
{
perror( "failed getting direccion using scanf()");
return( false );
}
// implied else
return(true);
}