scanf一直被跳过

时间:2014-10-23 21:10:36

标签: c scanf

在我的函数“leerdatos”中格式化“direccion”的scanf之后,它在第二个'for'循环中跳过“nro_corredor”。

我已经阅读了相关问题,但仍然没有得到答案。

我能做些什么来解决它?

#include <stdio.h>

typedef struct {
    int minutos;
    int segundos;
} s_tiempo;

typedef struct {
        int nro_corredor;   // guarda nro de corredor
        s_tiempo tiempo;      // guarda el tiempo que tardo el corredor
} carrera;

typedef struct {
        int nro_corredor;  // guarda nro de corredor
        char apellido[20];
        char nombres[20];
        char direccion[30];
} datos;

datos leerdatos(); //declaro la funcion leer

int main (void) {
    int cp; //cantidad de participantes.
    datos aux;
    printf("Ingrese la cantidad de participantes: ");
    scanf("%d",&cp);
    datos corredor[cp];
    carrera carreras[cp];
    printf("A continuacion, ingrese los datos de los corredores: \n");
    for(int i=0;i<cp;i++){
        aux = leerdatos();
        corredor[i] = aux;
    }
}

datos leerdatos(void) {
    datos participante;
    printf("\nIngrese el numero de corredor: ");
    scanf("%d",&participante.nro_corredor);
    printf("\nIngrese el apellido:\n");
    scanf("%s",participante.apellido);
    printf("\nIngrese los nombres:\n");
    scanf("%s",participante.nombres);
    printf("\nIngrese la direccion:\n");
    scanf(" %s\n",participante.direccion);
    return(participante);
}

3 个答案:

答案 0 :(得分:1)

scanf()

的使用不正确
// scanf(" %s\n", ...
scanf("%s", ...

'\n'之后的"%s"空白区域指示scanf()查找空白区域,直到跟随非白色空格。那个非白色空间被放回stdin。这可能意味着OP必须为第4个输入输入2 Enter

应始终检查scanf()返回值,看是否符合预期。

// scanf("%d",&participante.nro_corredor);
if (scanf("%d",&participante.nro_corredor) != 1) Handle_Error();

"%s"之前的"%d"scanf()之前加一个空格使没有区别。即使没有前导" ",这些说明符也会使用可选的空格。

建议使用fgets()读取用户输入( evil ),然后使用sscanf()strtok()strtol()等进行解析


注意:除了扫描集"%[...]"内,像' ''\t''\n'这样的空白区域和其他每个空格都执行相同的 :它们消耗任意数量的空白区域。 '\n'中的scanf(" %s\n",... 扫描1 '\n'。它扫描任何任何空白区域。它将继续扫描空白区域,包括多个 Enter ,直到输入EOF或非空格。然后将非白色空间放回stdin作为下一个要读取的字符。

答案 1 :(得分:0)

您面临的另一个问题是在调用scanf后需要刷新输入缓冲区(stdin)。正如chux所指出的那样,scanf不会消耗换行符'\n',而是将其留在输入缓冲区中作为下一个字符读取。每次使用scanf尤其是时多次调用scanf时,最好刷新输入缓冲区。刷新输入缓冲区的一种简单方法是:

int c = 0;                                  /* test int for getchar */
...
scanf("%d",&cp);
do { c=getchar(); } while ( c != '\n');     /* flush input buffer */

注意: fflushf 清除<{1}}中剩余的字符。

答案 2 :(得分:-1)

#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);
}