Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: meaf75 en 10 Abril 2016, 17:53 pm



Título: Duda solo ingresar numeros
Publicado por: meaf75 en 10 Abril 2016, 17:53 pm
Hola, estoy desarrollando una tarea y en esta me pide  ingresar un numero (todo bien hasta ahi) pero digamos la persona que esta usando el programa ingresa una letra le deberia decir: ingrese un numero pero en vez de eso cuando ingreso una letra me manda un error y se cierra, no se como poner que el valor a ingresar tiene que ser un numero y no una letra y si es una letra que lo devuelva al paso anterior hasta que ingrese un numero


Título: Re: Duda solo ingresar numeros
Publicado por: NOB2014 en 10 Abril 2016, 18:16 pm
Hola, meaf75. -
No tengo todavía mucha autoridad para responderte pero fíjate si este código te soluciona en parte tu problema, el único error es que si ingresas 12a te toma como válido el 12, tú dirás. -

Código
  1. #include <stdio.h>
  2. #include <limits.h>
  3.  
  4. int main( void ){
  5. int numero = 0, ch, ok;
  6.  
  7. do{
  8. printf("\n Ingresa un numero entero (maximo %u)....: ", UINT_MAX);
  9. ok = scanf("%d", &numero) == 1 && numero >= 1 && numero <= UINT_MAX;
  10.  
  11. while ((ch = getchar()) != EOF && ch != '\n');
  12. }while(!ok);
  13.  
  14. printf( "\n Ingreso...: %d", numero );
  15.  
  16. return 0;
  17. }

Saludos.
Daniel

(http://i68.tinypic.com/rt42vb.png)


Título: Re: Duda solo ingresar numeros
Publicado por: meaf75 en 10 Abril 2016, 19:17 pm
Huy me explicas jaja voy en primer semestre y no entiendo mucho lo que hay ahi


Título: Re: Duda solo ingresar numeros
Publicado por: LaiaxanIV en 10 Abril 2016, 19:46 pm
El código que ha subido NOB2014 está en C. Tiene que estar en c o en c++?
Si es en C, ya te explico el código.


Título: Re: Duda solo ingresar numeros
Publicado por: meaf75 en 10 Abril 2016, 21:47 pm
Pues yo estoy trabajado en pseint pero aprendiendo en c++ lo puedo pasar a pseint


Título: Re: Duda solo ingresar numeros
Publicado por: LaiaxanIV en 10 Abril 2016, 21:49 pm
Código
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int main(){
  5. string n;
  6. bool notnum = false;
  7. cout << "Ingresa un numero"  << endl;
  8. while(cin >> n){
  9. for(int i = 0; i < n.size() && !notnum; ++i){
  10. notnum = (n[i]< 48 || n[i]> 57);
  11. }
  12. if(notnum) cout << "Por favor, ingresa un numero correcto" << endl;
  13. else cout << "Numero correcto" << endl;
  14. }
  15. }

Mirate esto a ver si lo entiendes, si no enviame MP y te explico.


Título: Re: Duda solo ingresar numeros
Publicado por: HardForo en 15 Abril 2016, 17:53 pm
El ultimo codigo que se posteó (de @LaiaxanIV) esta escencialmente bien creo que por un boolean mal te queda en bucle infinito:

Citar
Ingresa un numero
uu
Por favor, ingresa un numero correcto
yy
Por favor, ingresa un numero correcto
55  <-- es correcto
Por favor, ingresa un numero correcto    <--  se vuelve a preguntar

Lo he modificado:

Código
  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4.  
  5. /*
  6. Lee un integer por teclado (C++)
  7. */
  8. int readint(string msg){
  9. string str_num;
  10. bool notnum = true;
  11.  
  12. cout << msg;
  13. cin >> str_num;
  14.  
  15. while(notnum){
  16. for(int i = 0; i < str_num.size();  i++){
  17. notnum = (str_num[i]< 48 || str_num[i]> 57);
  18.  
  19. if(notnum){
  20. cout << msg;
  21. cin >> str_num;
  22. break;
  23. }
  24. }
  25. }
  26.  
  27. return atoi(str_num.c_str());
  28. }
  29.  
  30.  
  31. int main(){
  32. int n;
  33. n = readint("Ingresa un numero: ");
  34. printf("Perfecto! el numero ingresado fue: %d",n);
  35.  
  36. return 0;
  37. }
  38.  


Ahora funciona bien y te aclaro que si el numero fuera un numero decimal (float) deberia aceptarse tambien el punto(.)


Título: Re: Duda solo ingresar numeros
Publicado por: HardForo en 16 Abril 2016, 04:54 am
He intentado traducir el codigo del compañero (que he modificado ligeramente) de C++ a C pero me explota!

Alguien podria hacerlo por mi para ver en que fallo ?  en C++ me funciona pero en C tengo un problema al pasar un string y querer utilizarlo como const char *

Ojala me iluminen  ;D


Título: Re: Duda solo ingresar numeros
Publicado por: crack81 en 16 Abril 2016, 06:21 am
Hola mirate este ejemplo, en vez de que la funcion readInt  lea, valide y regrese la conversion de string a entero

Mejor me cree una funcion para validar si un array de char en C seria valido para poder convertilo en un entero

Mi funcion lo unico que hace es recorrer la cadena y usando las funciones isdigit que viene en la bibilioteca ctype de C comprobamos que cada caracter es un entero valido

Si encontramos algo raro la funcion retorna un cero(false) sino regresa un uno(True)

ejemplo:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4.  
  5.  
  6. int isInteger(char possibleNumber[]){
  7.  
  8.    while(*possibleNumber){
  9.        if(!isdigit(*possibleNumber))return 0;
  10.        possibleNumber++;
  11.    }
  12.    return 1;
  13. }
  14.  
  15. int main()
  16. {
  17.    //Primer ejemplo
  18.    char number[]="352353";
  19.  
  20.    if(isInteger(number))
  21.        printf("%s","Es numero valido");
  22.    else
  23.        printf("%s","no es un numero valido");
  24.  
  25.    //Segundo ejemplo
  26.    char number2[20];
  27.    printf("%s","\n\nIngrese un valor valido\n");
  28.    scanf("%s",number2);
  29.  
  30.  
  31.    if(isInteger(number2))
  32.       printf("%s","Es numero valido");
  33.    else
  34.       printf("%s","no es un numero valido");
  35.  
  36.    return 0;
  37. }


Título: Re: Duda solo ingresar numeros
Publicado por: DanFire en 16 Abril 2016, 12:32 pm

Código:
int ingressaNumero() {

    int l(0);
    do {
        cout<< "Ingrese un numero : ";
        cin>>l;
        if (cin.fail()) {
            cout << "Te he pedido un numero , "
                 << "no tonterias!" << endl;

            cin.clear();

            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            l=-1;
        }
    } while(l<0);

    return l;


}



no te olvides de incluir <limits>
#include <iostream>
using namespace std;


Título: Re: Duda solo ingresar numeros
Publicado por: HardForo en 16 Abril 2016, 13:57 pm
@crack81 : me gustó mucho tu implementación  ;-)

Soy demasiado novatillo y te quiero consultar por esto:

Código
  1. int isInteger(char possibleNumber[]){
  2.  
  3.    while(*possibleNumber){
  4.        if(!isdigit(*possibleNumber))return 0;
  5.        possibleNumber++;
  6.    }
  7.    return 1;
  8. }
  9.  

char possibleNumber[] es un array, cierto ? porque no lo declaras como puntero a char (char*) sino con []

Sin embargo,... luego usas possibleNumber como si fuera un puntero (*possibleNumber) y por ello termino confundido  :o


Si me lo explicas serias muy amable  :xD

Gracias desde ya!


Título: Re: Duda solo ingresar numeros
Publicado por: MAFUS en 16 Abril 2016, 16:00 pm
Solución para Linux en compilador GCC, posiblemente funcione em MINGW para Windows ya que es un port de GCC.

El corazón del programa es la función getnum que sólo recibe números decimales (del 0 al 9) desde el teclado y devuelve un entero (int) con el valor igual al número introducido.

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <termios.h>
  4.  
  5. static struct termios old, new;
  6.  
  7. void init_terminal() {
  8.    tcgetattr(0, &old); /* old <- configuración actual del terminal
  9.                          * el 0 en el primer argumento es el descriptor
  10.                          * de archivo de stdin.
  11.                          */
  12.    new = old;          /* new copia el terminal original */
  13.    new.c_lflag &= ~ICANON;      /* Modo no canónico: la entrada se acepta
  14.                                   * caracter a caracter en vez de línea a
  15.                                   * línea.
  16.                                   */
  17.    new.c_lflag &= ~ECHO;        /* No hay eco del carácter introducido */
  18.    tcsetattr(0, TCSANOW, &new); /* Se guarda el nuevo comportamiento
  19.                                   * del terminal para usarlo a partir
  20.                                   * de ya.
  21.                                   */
  22. }
  23.  
  24. void reset_terminal() {
  25.    tcsetattr(0, TCSANOW, &old); /* Se vuelve al comportamiento original */
  26. }
  27.  
  28. int getnum() {
  29.    int num = 0;
  30.    int pos = 0;
  31.    int negative = 0;
  32.    char c;
  33.  
  34.    init_terminal(0);
  35.    while((c = getchar()) != '\n') {
  36.        if(pos == 0 && c == '-') {
  37.            putchar('-');
  38.            negative = 1;
  39.            ++pos;
  40.        }
  41.        if(c == 127 && pos) { /* 127 es la tecla retroceso */
  42.            num /= 10;
  43.            putchar('\b');
  44.            putchar(' ');
  45.            putchar('\b');
  46.            --pos;
  47.        }
  48.        if(isdigit(c)) {
  49.            putchar(c);
  50.            num *= 10;
  51.            num += c - '0';
  52.            ++pos;
  53.        }
  54.    }
  55.    if(negative)
  56.        num = -num;
  57.    reset_terminal();
  58.    putchar('\n');
  59.    return num;
  60. }
  61.  
  62. int main()
  63. {
  64.    int num;
  65.    printf("Introduzca un número: ");
  66.    num = getnum();
  67.    printf("%i", num);
  68.  
  69.    return 0;
  70. }


Título: Re: Duda solo ingresar numeros
Publicado por: crack81 en 16 Abril 2016, 16:08 pm
Hola boctulus, bueno me preguntas porque declare el parámetro como:
Código
  1. char possibleNumber[]
y no por un puntero a char, bueno la respuesta es que son lo mismo.
Cuando tu le indicas que le vas a pasar un arreglo como paremetro realmente le estas indicando que le estas pasando un puntero no importa el tipo de dato, la cosas cambia cuando es mas un de una dimension ejemplo 
Código
  1. arreglo[][10]
aqui ya tiene un sentido un poco mas profundo.

En fin si tu declaras tu funcion asi
Código
  1. int isInteger(char *possibleNumber)
no afecta en nada, ahora con respecto a porque trato  a possibleNumber como un puntero es que realmente es un puntero.

Cuando hago:
Código
  1. while(*possibleNumber)
estoy hanciendo varias operaciones una con el asterisco le estoy diciendo que me de el contenido de la direccion a donde esta apuntado la variable y al estar dentro de un while al mismo tiempo estoy haciendo una comparación booleana ya que en C o C++ el 1 significa true y el 0 False, asi que cuando accedo al contenido todo lo que sea diferente a 0 sera como decir
Código
  1. while(true)
.

Ahora hay que recordar que todas la cadenas en C o C++ "deberian" estar terminadas en nulo osea en CERO por ende el while vas a estar interando hasta que encuentre el final de la cadena osea hasta que encuentre el CERO

Pero es importante hacer esto
Código
  1. possibleNumber++
ya sino lo hacemos estariamos metidos en un bucle infinito ya que  possibleNumber++; lo que hace es apuntar a un siguiente caracter.

Bueno el tema es interesante si quieres saber mas detalladamente esto seria bueno hecharle una mirada a la artimetica de punteros y como manipular cadenas en C

Salutos...


Título: Re: Duda solo ingresar numeros
Publicado por: HardForo en 16 Abril 2016, 17:05 pm
Gracias crack, no sabia del azucar sintáctico que hace posible declarar un array como puntero pero como dices, tiene sentido  ;D


Título: Re: Duda solo ingresar numeros
Publicado por: HardForo en 29 Abril 2016, 21:04 pm
@LaiaxanIV : la idea está bien pero tiene una falla, creo es el valor por defecto del boolean