Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 6 Enero 2014, 21:45 pm



Título: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 6 Enero 2014, 21:45 pm
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.-

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4.  
  5. int main(){
  6. char numero[10] = "";
  7. int ok=0, i=0;
  8.  
  9. do{
  10. system("CLS");
  11. ok=0;
  12. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:", INT_MAX);
  13. fgets(numero, 10, stdin);
  14. numero[strlen(numero)-1]='\0';
  15.  
  16. for(i=0;numero[i] != '\0'; i++){
  17. if(numero[i] <=47 || numero[i] >=58){
  18. ok=1;
  19. printf("\n Solo debe ingresar numeros, Pulse una tecla para intentarlo nuevamente..."); getchar();
  20. }
  21. }
  22. }while(ok == 1);
  23.  
  24. printf("\n %s", numero);
  25. return 0;
  26. }

Bueno es todo.-
Saludos.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: amchacon en 6 Enero 2014, 23:41 pm
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.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 7 Enero 2014, 00:17 am
Hola.-
Citar
Si el número tiene 10 cifras y la primera cifra es 3 o más, entonces cabe.
Me parece que deberia ser hací.-
Citar
Si 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.-

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4.  
  5. int main(){
  6. char numero[11] = "", ch=0;
  7. int ok=0, i=0;
  8.  
  9. do{
  10. system("CLS");
  11. ok=0;
  12. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:", INT_MAX);
  13. fgets(numero, 10, stdin);
  14. numero[strlen(numero)-1]='\0';
  15. //while((ch = getchar()) != EOF && ch != '\n');
  16.  
  17. if(numero[0] == '0' || strlen(numero) == 0){
  18. ok=1;
  19. printf("\n Error, Pulse una tecla para intentarlo nuevamente..."); getchar();
  20. }
  21. else{
  22. for(i=0;numero[i] != '\0'; i++){
  23. if(numero[i] <=47 || numero[i] >=58){
  24. ok=1;
  25. printf("\n Solo debe ingresar numeros, Pulse una tecla para intentarlo nuevamente..."); getchar();
  26. }
  27. }
  28. }
  29. }while(ok == 1);
  30.  
  31.  
  32. printf("\n %s", numero);
  33. return 0;
  34. }
  35.  
Saludos


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: rir3760 en 7 Enero 2014, 03:40 am
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.
Para realizar esa operación puedes utilizar la función strtol (prototipo en <stdlib.h>), por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4. #include <errno.h>
  5. #include <ctype.h>
  6.  
  7. #define NUM_CHARS  256
  8.  
  9. int main(void)
  10. {
  11.   char cad[NUM_CHARS];
  12.   char *p;
  13.   long num;
  14.  
  15.   printf("Introduce un numero (%d .. %d): ", INT_MIN, INT_MAX);
  16.   fflush(stdout);
  17.   if (fgets(cad, NUM_CHARS, stdin) == NULL)
  18.      return EXIT_FAILURE;
  19.  
  20.   num = strtol(cad, &p, 10);
  21.  
  22.   if (num == 0 && p == cad)
  23.      puts("Entrada no valida");
  24.   else if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
  25.      puts("Numero fuera del rango valido para el tipo signed long");
  26.   else {
  27.      while (isspace(*p))
  28.         p++;
  29.  
  30.      if (*p != '\0')
  31.         puts("Caracteres invalidos al final de la cadena");
  32.      else
  33.         printf("El numero %ld es valido\n", num);
  34.   }
  35.  
  36.   return EXIT_SUCCESS;
  37. }
Solo falta agregar una validación (que el numero este en el rango INT_MIN .. INT_MAX).

Un saludo


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: blipi en 7 Enero 2014, 03:49 am
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
  1. try
  2. {
  3. std::string str(numero);
  4. std::string::size_type sz;
  5. int bytes = std::stoi(str, &sz);
  6. std::cout << "Bytes: " << bytes << std::endl;
  7. }
  8. catch(std::out_of_range&)
  9. {
  10. std::cout << "Fuera de limites!" << std::endl;
  11. }
  12. catch(std::invalid_argument&)
  13. {
  14. std::cout << "No es un numero!" << std::endl;
  15. }
  16.  

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


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 7 Enero 2014, 04:00 am
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.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 7 Enero 2014, 10:14 am
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
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. int main(){
  6. char numero[101] = "";
  7. int ok=0, i=0,ch=0;
  8. long long int num=0;
  9. do{
  10. system("CLS");
  11. ok=0;
  12. printf("\n Introduce el n%cmero que deseas convertir a binario\n maximo [%d]...:",163, INT_MAX);
  13. fflush(stdout);
  14. scanf ("%101[^\n]s",numero);
  15. num = atoll (numero);
  16. while((ch = getchar()) != EOF && ch != '\n');
  17. for(i=0;numero[i]; i++){
  18. if((strlen (numero)>10) ){
  19. ok=1;
  20. printf("\nTe has pasado en n%cmero de cifras. \n",163);
  21. break;
  22. }
  23. else if((numero[i] <=47 || numero[i] >=58) ){
  24. ok=1;
  25. printf("\n Solo debes ingresar n%cmeros. \n",163);
  26. break;
  27. }
  28. else if((num> INT_MAX) ){
  29. ok=1;
  30. printf("\n Te has pasado en tama%co.\n",164);
  31. break;
  32. }
  33.      }
  34.    system ("pause");
  35. }while(ok == 1);
  36. printf("\n %s\n", numero);
  37. return 0;
  38. }
  39.  

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:

...........................................
- Si el número tiene 10 cifras y la primera cifra es 3 o más, entonces cabe.
.....................................

Te despistaste, no cabe.



Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: amchacon en 7 Enero 2014, 11:51 am
Efectivamente, era no cabe

Qué 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.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 7 Enero 2014, 13:18 pm
.......................................................................
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:

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/indentado_zps239d695a.jpg)

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:


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: dato000 en 7 Enero 2014, 13:31 pm
Pues justamente llegue a un punto bastante parecido al del post, y estuve intentando lo de los acentos en C:

Código
  1. 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:


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 7 Enero 2014, 13:50 pm
Pues justamente llegue a un punto bastante parecido al del post, y estuve intentando lo de los acentos en C:

Código
  1. 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...[/size]
...............................................................................

Curiosamente, a pesar de estar mal ordenados los dos valores, me funcinó. No obstante gracias por la observación, ya lo corregi. Y una muestra de que sí funciona lo de los acentos y la ñ:

(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/INT_MAX_zps1bcc34d5.jpg)

;-)  ;-) Felices Navidades y Próspero Año Nuevo.  ;-)  ;-)


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


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: amchacon en 7 Enero 2014, 14:05 pm
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.
La única forma de detectar el desbordamiento es ver si sale negativo (ya que vuelve al valor mínimo). Si le ponemos un número muy grande, es posible que el número llege a los positivos de nuevo.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: dato000 en 7 Enero 2014, 14:10 pm
Ha de ser el compilador o el hecho de que yo lo trabajo desde linux, por ello no me funcionan las variables de acento:

(http://fotos.subefotos.com/94c3c45c98fcc88224a4f5538331ad32o.png)

Extraño, puede que el compilador entienda el uso de la variable de limite.

Estuve tratando de usar tu código con punteros, pero no he podido dar con el clavo, tengo un problema, si, ya se que es copia, pero siganme la corriente, porque trato de aprender el uso de punteros para este caso:

Código
  1. /*
  2.   Escribir una función que tenga como entrada una cadena y devuelva un número real.
  3.   La cadena contiene los carateres de un número real en formato decimal (por ejemplo,
  4.   la cadena "25.56" se ha de convertir en el correspondiente valor real).
  5.   */
  6.  
  7. #include <stdio.h>
  8. #include <limits.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. int main()
  13. {
  14.  
  15. char numero[101],ch=0;
  16. char *p_numero;
  17. int ok=0, i=0;
  18. long long int num=0;
  19.  
  20. do{
  21. system("clear");
  22. ok=0;
  23. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:  ", INT_MAX);
  24. fflush(stdout);
  25. scanf ("%101[^\n]s",numero);
  26.  
  27.                            num = atoll (numero);
  28. p_numero = &numero[0]; // p_numero = numero;
  29.  
  30. while((ch = getchar()) != EOF && ch != '\n');
  31.  
  32. //for(i=0;numero[i]; i++)
  33. while(*p_numero)
  34. {
  35.  
  36. if((strlen (p_numero)>11) )
  37. {
  38. ok=1;
  39. printf("\nTe has pasado en numero de cifras. \n");
  40. break;
  41. }
  42.  
  43. else if((*p_numero <=47 || *p_numero >=58) )
  44. {
  45. ok=1;
  46. printf("\n Solo debes ingresar numeros. \n");
  47. break;
  48. }
  49.  
  50. else if((num> INT_MAX) )
  51. {
  52. ok=1;
  53. printf("\n Te has pasado en tamanyo.\n");
  54. break;
  55. }
  56.                                            }
  57.  
  58.    }  while(ok == 1);
  59.  
  60.    printf("\n El número en la variable es: %s\n", numero);
  61.    return 0;
  62.  
  63. }
  64.  

Y tengo unos problemas que sinceramente no se como corregir, es decir, se cuál es el problema pero no se como solucionarlos, ayudenme con estos datos por favor mi gente:


Código
  1. num = atoll (numero);
Creo que no hay forma de pasarle el argumento de puntero, cierto?


Código
  1. while((ch = getchar()) != EOF && ch != '\n');
Realmente no entiendo porque es así, funciona, pero no se la razón, podrian explicarme un poco  :rolleyes: :rolleyes:


Código
  1. long long int num=0;
Nuevamente, no entiendo, podrian extender un poco sobre el tema, no me termino de convencer y quede enredado con tanta repetición de la repetidera.


Código
  1. #include <string.h>
  2. if((strlen (p_numero)>11) )
Esta es más una anotación, que me confirma que el compilador en windows es mucho más amable que uno en linux, al parecer debes tener más de un compilador que pasa por alto el uso de librerias estandar. O eso creo yo, por eso es que te pasa por alto ese tipo de "warnings" en el uso del programa.


Código
  1. fflush(stdout);
Ummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm porqué???


Código:
scanf ("%101[^\n]s",numero);
Eso es usando expresiones regulares??? porque 101 digitos??


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 7 Enero 2014, 14:31 pm
Hola.-
A ver qué les parece.-

- Si el numero tiene más de 10 cifras, entonces no cabe.
- Si el numero tiene menos de 10 cifras, entonces cabe.
- Si el número tiene 10 cifras y es mayor a 2.147.483.648  no cabe. 

Las 2 primeras son simples de verificar como si se ingresa 0, Enter sin haber ingresado nada o si se ingresó algo distinto a un número.-
La última lo haría de esta manera, sólo que tengo que elevar el resultado a la potencia correspondiente y desconozco como se hace, luego verifico si num es igual o menor a INT_MAX y estaría concluido (me parece).- 


Código:
#include <stdio.h>

int main(void){

char a[] = {2,1,4,7,4,8,3,6,4,9};
int i = 0;
unsigned int num=0;

while(i<=9){
num = num + a[i];
i++;
}

return 0;
}

Saludos


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: dato000 en 7 Enero 2014, 14:38 pm
bueno y en que momento solicita o imprime el número.  :rolleyes: :rolleyes:


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 7 Enero 2014, 14:59 pm
Hola.-
Simplemente es una práctica y una consulta para saber si mi idea tenía algún error y de hecho lo tiene, si se ingresa 10 cifras verificar que la primera sea =< a 2 porque si se ingresa 4294967296 tampoco cabe en un int sin signo.-
Cuando termine el código lo posteo para que algún recién iniciado como yo lo analice.-

Saludos


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: dato000 en 7 Enero 2014, 15:08 pm
Pues en tu código lo que esta haciendo es hacer una sumatoria con todos los digitos, no una conversión de cadena a int. De todas maneras sigue, yo también estoy haciendo mi investigación.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 8 Enero 2014, 19:14 pm
Pues en tu código lo que esta haciendo es hacer una sumatoria con todos los digitos, no una conversión de cadena a int. De todas maneras sigue, yo también estoy haciendo mi investigación.

Totalmente de acuerdo amigo dato000.

En principio lo que parece es querer usar la cadena a[],


Código:
#include <stdio.h>

int main(void){

char a[] = {2,1,4,7,4,8,3,6,4,9};
........................................................
}

donde está el INT_MAX. Lo cual me lleva a la lógica de comparar los dígitos de la cadena número con los de la cadena a[]. ¡Y vaya si funciona!, aunque me ha quedado un poco, como decirlo, poco compacto. Vamos, que lo tendría que mirar mejor para afinarlo, pero menos da una piedra. ;) ;) ;)

Aquí mi propuesta a lo que en principio pareces plantear. Si no es así ya nos lo comunicas:


Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. int main(){
  7. char numero[101] = "",a[] = {2,1,4,7,4,8,3,6,4,7}
  8. ;
  9. int ok=0, i=0,flag=0,ch=0;
  10. long long int num=0;
  11. do{
  12. //system("CLS");
  13. ok=0;
  14. printf("\n Introduce el n%cmero que deseas convertir a binario\n maximo [%d]...:",163, INT_MAX);
  15. fflush(stdout);
  16. scanf ("%101[^\n]s",numero);
  17. while((ch = getchar()) != EOF && ch != '\n');
  18. num = atoll (numero);
  19.    if((strlen (numero)>10) ){
  20.        ok=1;
  21.        printf("\nTe has pasado en n%cmero de cifras. \n",163);
  22.        break;
  23.      }
  24.      else if((numero[i] <=47 || numero[i] >=58) ){
  25.        ok=1;
  26.        printf("\n Solo debe ingresar n%cmeros. \n",163);
  27.        break;
  28.      }
  29.      /*else if((num> INT_MAX) ){
  30.         ok=1;
  31.         printf("\n Te has pasado en tama%co.\n",164);
  32.         break;*/
  33.        else {
  34.          for (i=0;numero[i];i++){
  35.            if ((int)(numero[i]-48)<(int)(a[i])){
  36.              printf ("\nEl numero es %s menor que %d \n",numero,INT_MAX);
  37.              flag=1;
  38.              break;
  39.              }
  40.            else if (numero[i]-48==(int)(a[i]) )
  41.              continue;
  42.            else {
  43.              printf ("\nEl numero es %s mayor que %d \n",numero,INT_MAX);
  44.              flag=1;
  45.              ok=1;
  46.              break;
  47.            }
  48.          }
  49.        if (flag==0)
  50.            printf ("\n\nEl numero es %s igual que %d \n",numero,INT_MAX);
  51.        }
  52.    putchar ('\n');
  53.    system ("pause");
  54. }while(ok == 1);
  55. printf("\n %s\n", numero);
  56. return 0;
  57. }
  58.  

El código, caso da que el número justito tenga diez cifras, diferencia si es menor, mayor o igual al INT_MAx. ;) ;) ;)

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

(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

P.D: Claro que también podemos usar las funciones de la librería string.h, stcmp  o strncmp, pero no tendría tanta gracia.

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. int main(){
  7. char numero[101] = "",ch=0,a[] = {"2147483647"};
  8. int ok=0, i=0,flag=0;
  9. long long int num=0;
  10. do{
  11. //system("CLS");
  12. ok=0;
  13. printf("\n Introduce el n%cmero que deseas convertir a binario\n maximo [%d]...:",163, INT_MAX);
  14. fflush(stdout);
  15. scanf ("%101[^\n]s",numero);
  16. while((ch = getchar()) != EOF && ch != '\n');
  17. num = atoll (numero);
  18.    if((strlen (numero)>10) ){
  19.        ok=1;
  20.        printf("\nTe has pasado en n%cmero de cifras. \n",163);
  21.        break;
  22.      }
  23.      else if((numero[i] <=47 || numero[i] >=58) ){
  24.        ok=1;
  25.        printf("\n Solo debe ingresar n%cmeros. \n",163);
  26.        break;
  27.      }
  28.      else {
  29.        flag=strcmp   (numero,a);
  30.        if (flag==0)
  31.          printf ("\n\nEl numero es %s igual que %d\n ",numero,INT_MAX);
  32.        else if (flag<0)
  33.          printf ("\nEl numero es %s menor que %d \n",numero,INT_MAX);
  34.        else if (flag>0){
  35.          printf ("\nEl numero es %s mayor que %d \n",numero,INT_MAX);
  36.          ok=1;
  37.        }
  38.      }
  39.    putchar ('\n');
  40.    system ("pause");
  41. }while(ok == 1);
  42. printf("\n %s\n", numero);
  43. return 0;
  44. }
  45.  


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 8 Enero 2014, 22:44 pm
Hola.
Bueno al fin puedo demostrar con este programa lo quería lograr.-

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. void charAint(const char[], int* ,int);
  7. void intAbinario(int, int*);
  8.  
  9.  
  10. int main(){
  11. char numeroChar[11] = "";
  12. unsigned int ok=0, i=0, longitud=0, numero, *ptrNumero = &numero;
  13.  
  14.  
  15. do{
  16. system("CLS");
  17. ok=0;
  18. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:", INT_MAX);
  19. fflush(stdout);
  20. fgets(numeroChar, 12, stdin);
  21. longitud = strlen(numeroChar);
  22. numeroChar[longitud-1] = '\0';
  23. if(numeroChar[0] == '\0' || numeroChar[0] == '0'){
  24. ok=1;
  25. printf("\n El numero ingresado debe ser mayor a cero\n\n Pulse una tecla para intentarlo nuevamente..."); getchar();
  26. }
  27. else{
  28. for(i=0;numeroChar[i] != '\0'; i++){
  29. if(numeroChar[i] <=47 || numeroChar[i] >=58){
  30. ok=1;
  31. printf("\n Debe ingresar solo numeros\n\n Pulse una tecla para intentarlo nuevamente..."); getchar();
  32. break;
  33. }
  34. }
  35. if(ok==0){
  36. i=0;
  37. if(longitud-1 == 10 && numeroChar[0] >= 2){
  38. i=1;
  39. }
  40. else{
  41. charAint(numeroChar, ptrNumero, longitud);
  42. if(*ptrNumero > INT_MAX){
  43. i=1;
  44. }
  45. }
  46. if(i == 1){
  47. ok=1;
  48. *ptrNumero = 0;
  49. printf("\n El numero ingresado supero el maximo permitido\n\n Pulse una tecla para intentarlo nuevamente..."); getchar();
  50. }
  51. }
  52. }
  53. }while(ok == 1);
  54.  
  55. intAbinario(numero, ptrNumero);
  56.  
  57. return 0;
  58. }
  59.  
  60. void charAint(const char numeroChar[], int *ptrNumero, int longitud){
  61. unsigned auxiliar=0, i=0;
  62.  
  63. while(i < longitud-1){
  64. auxiliar = numeroChar[i]-48;
  65. *ptrNumero=10* *ptrNumero+auxiliar;
  66. i++;
  67. }
  68. }
  69.  
  70. void intAbinario(int numero, int *ptrNumero){
  71. char binario[33] = "";
  72. unsigned int i=0, j=0, k=0, temp=0;
  73. do{
  74. binario[i] = '0' + numero%2;
  75. numero = numero/2;
  76. i++;
  77. }while (numero != 0);
  78.  
  79. binario[i] = '\0';
  80.  
  81. for (j = 0, k = strlen(binario)-1; j < k; j++, k--){
  82. temp = binario[j];
  83. binario[j] = binario[k];
  84. binario[k] = temp;
  85. }
  86. printf("\n\n En decimal %u --> en binario = %s\n\n", *ptrNumero, binario);
  87. }

No acepta los siguientes ingresos:
- 0  o vacio
- s25 o 25s
- número mayor a INT_MAX

En cuanto a la función charAint se que existe atoi pero en este caso es para practicar con punteros y funciones.-
Espero sugerencias para optimizarlo, muchas gracias a todos los que participaron para ayudarme a lograrlo.-

Saludos


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 9 Enero 2014, 07:49 am
Nada más probarlo surge una incongruencia. Te pongo una salida del código:

Citar

Introduce el numero que deseas convertir a binario
máximo [2147483647]...:12345

El numero ingresado supero el máximo permitido

Pulse una tecla para intentarlo nuevamente...

Introduce el numero que deseas convertir a binario
maximo [2147483647]...:1234567890

El numero ingresado supero el máximo permitido

Pulse una tecla para intentarlo nuevamente...

Introduce el numero que deseas convertir a binario
máximo [2147483647]...:

El error está, por un lado en que no inicializas la variable numero a cero[ y por otro en la condición/b]:

Código
  1. if(ok==0){
  2. i=0;
  3. if(longitud-1 == 10 && numeroChar[0] >= 2){
  4. i=1;
  5. }
  6.  

que debería ser:

Citar
if(ok==0){
            i=0;
            if(longitud-1 == 11 && numeroChar[0] >= 2){
               i=1;
            }

No obstante, no sé el por qué del uso  de punteros. No lo entiendo con la de alternativas que te hemos propuesto. Podías haberlo indicado desde el principio y nos hubiéramos ahorrado trabajo.;) ;) ;)




Saluditos! ..... !!!!    
 
 
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: NOB2014 en 9 Enero 2014, 13:34 pm
Hola leo.
Citar
…..nos hubiéramos ahorrado trabajo.
Mil disculpas.-

 
Citar
if(longitud-1 == 11 && numeroChar[0] >= 2){
               i=1;
 }
Muy bien, muchas gracias grave error el mio y lo estoy revisando porque me parece que hay otro.-

Citar
….no inicializas la variable numero a cero

Esta parte no la entiendo, lo voy a analizar, en crudo te diré que el paso de la variable a la función es para pasarla como valor y no como referencia (*ptrNumero
) para no destruir los datos que contiene, decime por favor tu conclusión.-  

Saludos.


Título: Re: Pasar de cadena(char) a entero(int) sin sobrepasar el máximo permitido.
Publicado por: leosansan en 9 Enero 2014, 14:35 pm
Código:
[code]
.......................................................
Estuve tratando de usar tu código con punteros, pero no he podido dar con el clavo, tengo un problema, si, ya se que es copia, pero sigan me la corriente, porque trato de aprender el uso de punteros para este caso:
Código
  1.  
  2. #include <stdio.h>
  3. ...................................
  4.  
  5. ......................................
  6.                       while(*p_numero)
  7. ....................................
  8.  
  9.  


Antes que nada aclararte que no es mi fuerte el tema de punteros, pero como veo que no ha habido respuesta de nadie, te aporto alguna idea de mi cosecha, seguramente muy mejorable.

Por lo que veo el while se queda clavado, en el sentido de que entra  en un bucle porque sólo está recibiendo el primer caracter de la cadena y al no incrementarlo en el interior del while de alguna manera pues eso, no sale de un bucle.

Fíjate que yo pondría ;


Código
  1.            i=0;
  2.            while(*p_numero)
  3.          {
  4.        ..............................
  5.          *p_numero++;
  6.          }
  7.  

así recibe de entrada el primer caracter de la cadena y con el *p_numero++ al final, pero dentro del while, el siguiente valor que toma en el while ya estará incrementado, es decir, tomará el segundo caracter y así sucesivamente.

¡Jope!, esto es un rollo, mejor te paso una posible opción:

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. int main()
  7. {
  8.  
  9. char numero[101],ch=0;
  10. char *p_numero;
  11. int ok=0, i=0;
  12. long long int num=0;
  13.  
  14. do{
  15. ok=0;
  16. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:  ", INT_MAX);
  17. fflush(stdout);
  18. scanf ("%101[^\n]s",numero);
  19.    num = atoll (numero);
  20. p_numero =& numero[0]; // p_numero = numero;
  21. while((ch = getchar()) != EOF && ch != '\n');
  22. while(*p_numero)
  23.  {
  24. if((strlen (numero)>10) )
  25. {
  26. ok=1;
  27. printf("\nTe has pasado en numero de cifras. \n");
  28. break;
  29. }
  30. else if((*p_numero <=47 || *p_numero >=58) )
  31. {
  32. ok=1;
  33. printf("\n Solo debes ingresar numeros. \n");
  34. break;
  35. }
  36. else if((num> INT_MAX) )
  37. {
  38. ok=1;
  39. printf("\n Te has pasado en tamanyo.\n");
  40. getchar();
  41. break;
  42. }
  43. *p_numero++;
  44.      }
  45.    }  while(ok == 1);
  46.    printf("\n El número en la variable es: %s\n", numero);
  47.    return 0;
  48. }
  49.  

Y tengo unos problemas que sinceramente no se como corregir, es decir, se cuál es el problema pero no se como solucionarlos, ayúdenme con estos datos por favor mi gente:

Código
  1. num = atoll (numero);
Creo que no hay forma de pasarle el argumento de puntero, cierto?


Código
  1. while((ch = getchar()) != EOF && ch != '\n');


Ese seria a mi entender otro caso distinto. Lo que propones en el fondo es un puntero  array que almacene la misma cadena que la cadena numero, para luego poder invocar al puntero desde strol.

Para ello creo el puntero, con asignación de memoria incluida, fíjate por cierto que en malloc aparece 11*1, que se corresponden con el tamaño de la cadena que voy a crear y ocupando cada elemento de la cadena un char, que sólo ocupan 1, de ahí el *1. Vamos que ese 1 del 11*1 sería en realidad *sizeof (char) .

Observa además como accedo a las distintas posiciones de memoria del puntero y como es el incremento de puntero, otra vez al final del while:


Código
  1.          ..............
  2.           while(*(p_numero+i))
  3.          {
  4.             .....................
  5.           *(p_numero+i)
  6.            ..............................
  7.            i++;
  8.           }
  9.  

Para que lo veas mejor:

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. int main()
  7. {
  8.  
  9. char numero[101],ch=0;
  10. char *p_numero;
  11. int ok=0, i=0;
  12. long long int num=0;
  13.  
  14. do{
  15. ok=0;
  16. printf("\n Introduce el numero que deseas convertir a binario\n maximo [%d]...:  ", INT_MAX);
  17. fflush(stdout);
  18. scanf ("%101[^\n]s",numero);
  19.    num = atoll (numero);
  20. p_numero =& numero[0]; // p_numero = numero;
  21. while((ch = getchar()) != EOF && ch != '\n');
  22. while(*p_numero)
  23.  {
  24. if((strlen (numero)>10) )
  25. {
  26. ok=1;
  27. printf("\nTe has pasado en numero de cifras. \n");
  28. break;
  29. }
  30. else if((*p_numero <=47 || *p_numero >=58) )
  31. {
  32. ok=1;
  33. printf("\n Solo debes ingresar numeros. \n");
  34. break;
  35. }
  36. else if((num> INT_MAX) )
  37. {
  38. ok=1;
  39. printf("\n Te has pasado en tamanyo.\n");
  40. getchar();
  41. break;
  42. }
  43. *p_numero++;
  44.      }
  45.    }  while(ok == 1);
  46.    printf("\n El número en la variable es: %s\n", numero);
  47.    free(p_numero );
  48.    return 0;
  49. }
  50.  

Y tengo unos problemas que sinceramente no se como corregir, es decir, se cuál es el problema pero no se como solucionarlos, ayúdenme con estos datos por favor mi gente:


Código
  1.  
  2. while((ch = getchar()) != EOF && ch != '\n');
[/code]

Realmente no entiendo porque es así, funciona, pero no se la razón, podrían explicarme un poco  :rolleyes: :rolleyes:


Lo del while anterior es para limpiar el buffer. Es un tema muy manido ya. Te aconsejo usar el motor de búsqueda para que veas más sobre él, pero en esencia hace eso: limpiar el buffer después de un scanf.


Código
  1. long long int num=0;
Nuevamente, no entiendo, podrian extender un poco sobre el tema, no me termino de convencer y quede enredado con tanta repetición de la repetidera.


Citar
             #include <string.h>
              if((strlen (p_numero)>11) )

Por un lado el uso del tipo long long int es para que se pueda tomar comparar la variable num con el valor máximo de un int, que lo representa INT_MAX. ¿qué pasaría si num lo declaramos simplemente como int?. Pues que si introduces un número mayor que INT_MAX  num tomaría cualquier valor impredecible, por sobrepasar el límite que impone INT_MAX. Para evitar eso es por lo que declaramos num como long long int, ya que este tipo admite hasta diez cifras, muy por encima de las diez del tipo int, así estamos seguros que si el usuario introduce más de diez cifras, pero menos de veinte, se puede guardar el valor de dicho número en la variable num y así podemos comparar con el valor que representa INT_MAX.

Y por otro lado, hay un pequeño error en lo de strlen. Es:


Citar

                                  #include <string.h>
                                    ...................................
                           if((strlen (p_numero)>10) )
                                ................................................

[/quote]

.......................................
Código
  1. fflush(stdout);
Ummmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm porqué???
.............................................
Código:
scanf ("%101[^\n]s",numero);
Eso es usando expresiones regulares??? porque 101 digitos??

En realidad se supone que se van a tomar un máximo de diez dígitos, pero podría ser que el usuario introduzca más.

Tal como está el código se podría limitar a los veinte que como máximo acepta el tipo long long int, pero es que si se prescinde del uso de la variable num el código podría admitir cualquier cantidad de dígitos para pasar  a binario. En ese caso el valor de 101 se sustituiría por el número de cifras máximo que establezca el programador.


Y lodel fflush(stdout) es para asegurar, después de un printf no terminado en \n, que se vuelque toda la información a la salida estándar, en este caso la pantalla.

Espero que te sirvan mis humildes respuestas, mejorables seguro por los más entendido que yo, que no dejo de ser más que un aficionad reciente a este mundillo del C. Pero menos da una piedra ............... ;) ;) ;)


Un fuerte saludo amigo dato000

Y por otro lado:

Hola leo.Mil disculpas.-

 Muy bien, muchas gracias grave error el mio y lo estoy revisando porque me parece que hay otro.-
 
Esta parte no la entiendo, lo voy a analizar, en crudo te diré que el paso de la variable a la función es para pasarla como valor y no como referencia (*ptrNumero
) para no destruir los datos que contiene,
decime por favor tu conclusión.-  

Saludos.


De nada y que te comente sobre los punteros era simplemente que si lo hubieras comentado la ayuda habría sido más en tu línea. ;) ;) ;)

Respecto al paso por valor o referencia, en lo poco que entiendo, los punteros se hacen siempre por referencia ya que usan una dirección a la que apuntan. Por otro lado en la función vas a modificar el valor de *ptrNumero, con lo que el paso por referencia está más que justificado.

Citar
….no inicializas la variable numero a cero

Es que la variable *ptrNumero es acumulativa, por lo que necesita un valor inicial concreto, si no toma un valor basura y el resultado es incierto, Observa lo que haces con dicha variable:


Código
  1.                    ...........................................
  2.                       *ptrNumero=10* (*ptrNumero)+auxiliar;
  3.                     ........................................
  4.  

¿Y cual es el primer valor por el que multiplica *ptrNumero?. ;) ;) ;)

Espero haber entendido/respondido a tus dudas. Y si no es así insiste.  :laugh:


Saluditos! ..... !!!!    
 
 
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)