Acabo de comenzar a aprender el lenguaje de C, y me encantaría tu ayuda para limpiar / simplificar mi código si conoces una mejor manera de llegar a lo siguiente.

Quiero que un programa solicite un número, y si lo encuentra, proceda a imprimir y finalizar, sin embargo, si se ingresa algo más (por ejemplo, una tecla de letra), entonces quiero que el programa realice un bucle solicitando un número hasta que uno sea dado.

Comencé usando un simple comando de entrada scanf, pero esto pareció entrar en un bucle infinito cuando traté de verificar si se ingresó un número válido (como los definimos).

Entonces, en cambio, terminé con esto, jugando / buscando en línea, ¡pero me encantaría saber si hay alguna manera más eficiente!

//
//  Name & Age Program
//  Created by Ben Warren on 1/3/18.
//


#include <stdio.h>
int main (void)
{

    //Setting up variables
    int num;
    char line[10]; /* this is for input */



    //Collecting input
    printf("Please enter any number? \t");
    scanf("%d", &num);


    //If Invalid input
    while (num==0)
    {
        printf("\nTry again:\t");
        fgets(line, 10, stdin); //turning input into line array
        sscanf(line, "%d",&num); //scaning for number inside line and storing it as 'num'
        if (num==0) printf("\nThat's not an number!");
    }


    //If Valid input
    {
        printf("\n%d is nice number, thank you! \n\n", num);
    *}*


    return 0;

}
c
0
Ben Warren 2 mar. 2018 a las 02:19

4 respuestas

La mejor respuesta

En lugar de verificar si el valor es diferente a 0, verifique el valor de retorno de sscanf. Devuelve el número de conversiones que realizó. En su caso, debería ser 1. A menos que el valor de retorno sea 1, siga pidiendo un número.

#include <stdio.h>

int main(void)
{
    int ret, num;
    char line[1024];

    do {
        printf("Enter a number: ");
        fflush(stdout);

        if(fgets(line, sizeof line, stdin) == NULL)
        {
            fprintf(stderr, "Cannot read from stdin anymore\n");
            return 1;
        }

        ret = sscanf(line, "%d", &num);

        if(ret != 1)
            fprintf(stderr, "That was not a number! Try again.\n");

    } while(ret != 1);

    printf("The number you entered is: %d\n", num);

    return 0;
}
3
Pablo 1 mar. 2018 a las 23:25

0 (cero) es un número ...

Pero veo lo que quieres hacer ... Puede verificar un número válido, utilizando isdigit o una combinación de funciones similares

Creo que también es importante seguir los consejos de otras respuestas para usar el valor de retorno de scanf usando código como:

int ret = scanf("%d", &num);

Y examinando ret por éxito o fracaso de scanf.

0
Grantly 1 mar. 2018 a las 23:29

Considere utilizar strtol para analizar una cadena durante un int largo. Esto también le permite detectar caracteres finales. En este ejemplo, si el carácter final no es una nueva línea, la entrada se puede rechazar. strtol también puede detectar valores de desbordamiento. Lea la documentación para ver cómo funciona.

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
    //Setting up variables
    long int num = 0;
    char line[40] = ""; /* this is for input */
    char *parsed = NULL;

    printf("Please enter any number? \t");
    fflush ( stdout);
    while ( fgets(line, 40, stdin))
    {
        parsed = line;//set parsed to point to start of line
        num = strtol ( line, &parsed, 10);
        if ( parsed == line) {//if parsed equals start of line there was no integer
            printf("Please enter a number? \t");
            printf("\nTry again:\t");
            fflush ( stdout);
            continue;
        }
        if ( '\n' != *parsed) {//if the last character is not a newline reject the input
            printf("Please enter only a number? \t");
            printf("\nTry again:\t");
            fflush ( stdout);
        }
        else {
            break;
        }
    }
    if ( !parsed || '\n' != *parsed) {
        fprintf ( stderr, "problem fgets\n");
        return 0;
    }
    printf("\n%ld is nice number, thank you! \n\n", num);

    return 0;
}
1
user3121023 2 mar. 2018 a las 01:19

Ese no es un mal enfoque para alguien nuevo en C. Una pequeña mejora sería verificar el valor de retorno de scanf(), ya que devuelve el número de argumentos recuperados con éxito. Entonces podría evitar confiar en que num sea 0 para indicar que la entrada fue válida. A menos que desee marcar específicamente 0 como entrada no válida.

int ret = scanf("%d", &num);

ret == 1 significaría que un número entero se leyó con éxito en num, ret == 0 significaría que no fue así.

1
Stephen Docy 1 mar. 2018 a las 23:26