繁体   English   中英

scanf不断被跳过

[英]The scanf keeps being skipped

在函数“ 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);
}

scanf()用法不正确

// scanf(" %s\n", ...
scanf("%s", ...

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

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

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

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

建议使用fgets()读取用户输入(这是邪恶的 ),然后使用sscanf()strtok()strtol()等进行解析。


注意:除了在扫描集"%[...]"内外,像' ''\\t''\\n'之类的空白,其他每个都执行相同的操作 :它们消耗任意数量的空白。 '\\n'scanf(" %s\\n",... 扫描1 '\\n' 。它扫描任意数量 任何空白的。它将使扫描空白,包括多输入直到输入EOF或非空格,然后将该非空格放回stdin作为下一个要读取的字符。

您面临的另一个问题是在调用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不会留在明确的字符stdin

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM