sirve sintaxis qué que punteros para lenguaje leer hace función funciona funcion como cadenas c floating-point int scanf

sintaxis - scanf %d



Cómo obtener enteros y flotantes de entrada sin `scanf()` en c? (3)

¿Cómo puedo asignar valores enteros y flotantes dados por el usuario a una variable o matriz sin usar scanf() ?

Al igual que tenemos getchar , fgetc , fgets ... etc para char y string , ¿hay alguna función para flotantes y enteros?


¿Hay alguna función para flotantes y enteros?

Sí, es scanf() , pero OP no quiere usar eso.

¿Cómo obtener la entrada de entero y flotante sin scanf() ?

Esta no es una tarea trivial que hacer simplemente como scanf("%d", &some_int) , scanf("%f", &some_float) .

El principal problema es dejar de leer los caracteres una vez que se haya consumido la entrada válida más larga, esto podría estar en el medio de una línea de entrada del usuario. No encontré una solución robusta.

En cambio, consideró el problema de leer una línea de entrada del usuario por un entero de long . Leer un float es similar. Cambios necesarios cerca de las líneas ***

Todavía se produce el problema de la longitud de texto finito. El código siguiente supone que la entrada válida está compuesta por hasta el doble del máximo necesario para imprimir una long .

El desbordamiento es un problema abordado aquí. Recordar con scanf() , OF / UF es un comportamiento indefinido.

La idea central es leer una línea omitiendo espacios en blanco, leyendo N caracteres y luego buscando cualquier espacio no blanco después de eso. Luego analiza el buffer.

#include <ctype.h> #include <errno.h> #include <limits.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <string.h> // character array size needed to represent all `long` #define INT_STR_SIZE (sizeof(long)*CHAR_BIT/3 + 3) #define INT_BUF_SIZE (INT_STR_SIZE*2) int readline_long(long *dest) { // *** int ch; while (isspace(ch = getchar()) && ch != ''/n'') { ; } if (ch == EOF) return EOF; ungetc(ch, stdin); char buf[INT_BUF_SIZE]; // *** if (fgets(buf, sizeof buf, stdin) == NULL) return EOF; if (strchr(buf, ''/n'') == NULL) { // Get rest of line bool only_white_space = true; while ((ch = getchar()) != ''/n'' && ch != EOF) { if (!isspace(ch)) only_white_space = false; // consume rest of line } if (!only_white_space) return 0; // extra junk } char *endptr; errno = 0; long y = strtol(buf, &endptr, 10); // *** if (buf == endptr) return false; // no conversion while (isspace((unsigned char) *endptr)) { endptr++; } if (*endptr) return 0; // extra junk *dest = y; return 1; }

Código de prueba

int main(void) { long lg; int retval; while ((retval = readline_long(&lg)) != EOF) { printf("retval = %d", retval); if (retval > 0) printf(" val = %ld", lg); if (errno) printf(" errno = %d", errno); putchar(''/n''); fflush(stdout); } }


Hace años escribí esto, Probado en VS2017 y todavía funciona. Muy simple, no muy bueno, pero tal vez puedas usarlo para algo

#define INT_CONVERTED (1 << 0) #define FLOAT_CONVERTED (1 << 1) char *strlwr(char *str) { char *ptr = str; while (*ptr) { *ptr = tolower(*ptr); ptr++; } return str; } int NumberOfDots(char *s) { int dots = 0; while (*s) dots += *s++ == ''.''; return dots; } int NOTstrcasechr(char *str, int ch) { return strchr(str, ch) == NULL && strchr(str, toupper(ch)) == NULL; } int ReadNumber(double *db, int *in) { int result = 0; do { char str[100]; int dots; result = 0; printf("Enter number: "); fgets(str, 100, stdin); if ((dots = NumberOfDots(str)) > 1) str[0] = ''/0''; if (sscanf(str, "%lf", db) == 1) { result |= FLOAT_CONVERTED; } if (!result || (!dots && NOTstrcasechr(str, ''e''))) if (NOTstrcasechr(str, ''x'')) { if (sscanf(str, "%d", in) == 1) { result |= INT_CONVERTED; } } else if(result) { result |= INT_CONVERTED; *in = (int)*db; } if (strstr(strlwr(str), "exit") != NULL) result = -1; } while (!result); return result; } int main(int argc, char **argv) { double db; int in; int result; while ((result = ReadNumber(&db, &in)) != -1) { if (result & FLOAT_CONVERTED) printf("Float = %lf ", db); if (result & INT_CONVERTED) printf("Integer = %d ", in); printf("/n/r"); } return 0; } Enter number: xfdsfdsfdsf Enter number: rthdgfhghg Enter number: 0x4567 Float = 17767.000000 Integer = 17767 Enter number: 3e67 Float = 30000000000000000978680950144401383192292617328216608963406365458432.000000 Enter number: 54567 Float = 54567.000000 Integer = 54567 Enter number: dfgdfgdfgdfgdgg Enter number: 3456 Float = 3456.000000 Integer = 3456 Enter number: 12354654465454654654565567567576 Float = 12354654465454653961713368432640.000000 Integer = -1 Enter number: exit


No hay funciones para leer números enteros y flotantes, pero puede usar fgets con strtol para enteros y strtof para flotantes:

// floats: char str_f[20]; float f; fgets (str_f, 20, stdin); f = strtof(str_f, NULL); // integers: char str_i[20]; int i; fgets(str_i, 20, stdin); i = strtol(str_i, NULL, 0);

También puede usar atoi para enteros, pero no se recomienda porque atoi no detecta errores y se considera obsoleto.

Si desea detectar errores, puede usar el siguiente código:

// floats: char *endptr_f; char str_f[20]; float f; fgets (str_f, 20, stdin); f = strtof(str_f, &endptr_f); if (*endptr_f != ''/n'' || str_f[0] == ''/n'' || endptr_f == str_f) { printf("ERROR: /"%s/" is an invalid float!/n", str_f); } // integers: char *endptr_i; char str_i[20]; int i; fgets(str_i, 20, stdin); i = strtol(str_i, &endptr_i, 0); if (*endptr_i != ''/n'' || str_i[0] == ''/n'' || endptr_i == str_i) { printf("ERROR: /"%s/" is an invalid integer!/n", str_i); }