Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.

Iniciado por NOB2014, 6 Enero 2014, 21:45 PM

0 Miembros y 1 Visitante están viendo este tema.

NOB2014

Hola.-
Les dejo un pequeño programa que luego voy a seguir completando, lo que quiero saber es si se puede antes de convertir la cadena a entero verificar si el número ingresado sobrepasa el máximo permitido por el tipo int.-

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(){
char numero[10] = "";
int ok=0, i=0;

do{
system("CLS");
ok=0;
printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:", INT_MAX);
fgets(numero, 10, stdin);
numero[strlen(numero)-1]='\0';

for(i=0;numero[i] != '\0'; i++){
if(numero[i] <=47 || numero[i] >=58){
ok=1;
printf("\n Solo debe ingresar numeros, Pulse una tecla para intentarlo nuevamente..."); getchar();
}
}
}while(ok == 1);

printf("\n %s", numero);
return 0;
}


Bueno es todo.-
Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

amchacon

Los enteros (con signo) tiene el valor máximo de 2.147.483.648

Por lo que el algoritmo sería:

- Si el numero tiene mas de 10 cifras, entonces no cabe.
- Si el numero tiene menos de 10 cifras, entonces cabe.
- Si el número tiene 10 cifras y la primera cifra es 3 o más, entonces cabe.
- Transforma el número, si es negativo entonces no cabe.

Por cierto para quepa un entero el array de char debe ser de 11 caracteres al menos.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

NOB2014

Hola.-
CitarSi el número tiene 10 cifras y la primera cifra es 3 o más, entonces cabe.
Me parece que deberia ser hací.-
CitarSi el número tiene 10 cifras y la primera cifra es 3 o más, entonces NO cabe.
Bien la idea la capte, sólo que tengo 2 problemas.-
Qué pasa si el número ingresado es 2.247.483.648 tampoco cabe.-
La otra es que tengo que apretar Enter después de limpiar el buffer de teclado.-
Te aclaro que le hice otras validaciones.-

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(){
char numero[11] = "", ch=0;
int ok=0, i=0;

do{
system("CLS");
ok=0;
printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:", INT_MAX);
fgets(numero, 10, stdin);
numero[strlen(numero)-1]='\0';
//while((ch = getchar()) != EOF && ch != '\n');

if(numero[0] == '0' || strlen(numero) == 0){
ok=1;
printf("\n Error, Pulse una tecla para intentarlo nuevamente..."); getchar();
}
else{
for(i=0;numero[i] != '\0'; i++){
if(numero[i] <=47 || numero[i] >=58){
ok=1;
printf("\n Solo debe ingresar numeros, Pulse una tecla para intentarlo nuevamente..."); getchar();
}
}
}
}while(ok == 1);


printf("\n %s", numero);
return 0;
}

Saludos
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

rir3760

Cita de: NOB2014 en  6 Enero 2014, 21:45 PMlo que quiero saber es si se puede antes de convertir la cadena a entero verificar si el número ingresado sobrepasa el máximo permitido por el tipo int.
Para realizar esa operación puedes utilizar la función strtol (prototipo en <stdlib.h>), por ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>

#define NUM_CHARS  256

int main(void)
{
   char cad[NUM_CHARS];
   char *p;
   long num;
   
   printf("Introduce un numero (%d .. %d): ", INT_MIN, INT_MAX);
   fflush(stdout);
   if (fgets(cad, NUM_CHARS, stdin) == NULL)
      return EXIT_FAILURE;
   
   num = strtol(cad, &p, 10);
   
   if (num == 0 && p == cad)
      puts("Entrada no valida");
   else if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
      puts("Numero fuera del rango valido para el tipo signed long");
   else {
      while (isspace(*p))
         p++;
     
      if (*p != '\0')
         puts("Caracteres invalidos al final de la cadena");
      else
         printf("El numero %ld es valido\n", num);
   }
   
   return EXIT_SUCCESS;
}

Solo falta agregar una validación (que el numero este en el rango INT_MIN .. INT_MAX).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

blipi

Si te quieres complicar aun menos, y suponiendo que no te importe usar C++, std::stoi es tu solución:

http://www.cplusplus.com/reference/string/stoi/

Con eso y un simple bloque try/catch, lo tienes solucionado.

Código (cpp) [Seleccionar]

try
{
std::string str(numero);
std::string::size_type sz;
int bytes = std::stoi(str, &sz);
std::cout << "Bytes: " << bytes << std::endl;
}
catch(std::out_of_range&)
{
std::cout << "Fuera de limites!" << std::endl;
}
catch(std::invalid_argument&)
{
std::cout << "No es un numero!" << std::endl;
}


Solo te faltaría convertir a binario (por bytes, entendemos que es el numero tal cual)

NOB2014

Hola.
Por el momento estoy aprendiendo C y ya la respuesta de rir3760 me resulta un tanto difícil de interpretar pero lo voy a intentar.-

Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

leosansan

Como es mi costumbre, sin tratar de modificar en exceso el código que planteas, hago una simple comparación entre la variable num, convertida a long long int, con INT_MAX, suponiendo que lo que se trata es de un INT positivo, si no coméntalo.

¿Y por qué uso el tipo long long int?. Porque si uso el tipo INT para num, si introduzco un número de 10 cifras, pero mayor que INT_MAX por ser mayor a ese límite, tomaría un valor basura y la comparación no sería correcta. Simple pero efectivo. ;) ;) ;)


Código (cpp) [Seleccionar]

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
int main(){
char numero[101] = "";
int ok=0, i=0,ch=0;
long long int num=0;
do{
system("CLS");
ok=0;
printf("\n Introduce el n%cmero que deseas convertir a binario\n maximo [%d]...:",163, INT_MAX);
fflush(stdout);
scanf ("%101[^\n]s",numero);
num = atoll (numero);
while((ch = getchar()) != EOF && ch != '\n');
for(i=0;numero[i]; i++){
if((strlen (numero)>10) ){
ok=1;
printf("\nTe has pasado en n%cmero de cifras. \n",163);
break;
}
else if((numero[i] <=47 || numero[i] >=58) ){
ok=1;
printf("\n Solo debes ingresar n%cmeros. \n",163);
break;
}
else if((num> INT_MAX) ){
ok=1;
printf("\n Te has pasado en tama%co.\n",164);
break;
}
     }
   system ("pause");
}while(ok == 1);
printf("\n %s\n", numero);
return 0;
}


Por cierto, los números que aparecen al final de los printf son los códigos ASCII par poder ver en pantalla la ñ y los acentos :rolleyes: :rolleyes: :rolleyes:.

¡¡¡¡ Saluditos! ..... !!!!


:rolleyes: ;) ;) ;) :rolleyes:

P.D:

Cita de: amchacon en  6 Enero 2014, 23:41 PM
...........................................
- Si el número tiene 10 cifras y la primera cifra es 3 o más, entonces cabe.
.....................................

Te despistaste, no cabe.


amchacon

Efectivamente, era no cabe

Cita de: NOB2014 en  7 Enero 2014, 00:17 AMQué pasa si el número ingresado es 2.247.483.648 tampoco cabe.-
Eso ya lo tengo verificado, mira el último punto.

Si es mayor de 2.247.483.648 pero menor que 3 mil millones, entonces al pasarlo a entero desbordará y se quedará negativo.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

leosansan

Cita de: amchacon en  7 Enero 2014, 11:51 AM
.......................................................................
Si es mayor de 2.247.483.648 pero menor que 3 mil millones, entonces al pasarlo a entero desbordará y se quedará negativo.

Me he levantado, muy de madrugada, y estoy "pijito". ;)

Esta vez te sobra en la frase lo de "pero menor que 3 mil millones". Es suficiente que sea mayor de 2.247.483.647, y digo bien mayor que no igual, para que se produzca desbordamiento.

Lo dicho, estoy "pijito". ;)

Un fuerte abrazo y que en este año, y los venideros, te sean favorables los hados.  :rolleyes: :rolleyes: :rolleyes:

¡¡¡¡ Saluditos! ..... !!!!

:rolleyes: ;) ;) ;) :rolleyes:

P.D. Por cierto, yo el código lo tengo bien indentado:


pero al hacer el pegado entre las etiquetas code no sé que pasa que los distorsiona. ¡¡¡Horror!!!,espero que no se trate de un mal augurio, lo que me faltaba.  :huh: :huh: :huh:

dato000

Pues justamente llegue a un punto bastante parecido al del post, y estuve intentando lo de los acentos en C:

printf("\n Introduce el n%cmero que deseas convertir a binario\n maximo [%d]...:", 163, INT_MAX);

Una cosa, esta al reves, primero deberia ir la variable tipo ASCII (163 ---> ù) y luego la que contiene el valor máximo de una variable tipo entera (INT_MAX---> #define INT_MAX 0x7FFF/0x7FFFFFFF ---> 2.247.483.647)

Ahora, lo de los acentos, pues bueno. No me funciono...

Voy a trabajar un poco en este punto, ya me faltan pocos ejercicios para terminar el tema de punteros  :laugh: :laugh: