elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Programa que identifique que tipo de dato se introduce C++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: Programa que identifique que tipo de dato se introduce C++  (Leído 15,732 veces)
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #10 en: 8 Febrero 2014, 21:49 pm »

Se puede hacer, pero tendrías que comprobar la cadena a ver si se puede convertir. Despues de saber si se puede convertir, tendrías que convertirla.

Aquí te pongo un par de códigos:

Saber a que tipos de dato se puede transformar:
Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. enum type{
  6.    /**    TYPES    **/
  7.    type_bool     = 0b000000000001,
  8.    type_char     = 0b000000000010,
  9.    type_uchar    = 0b000000000100,
  10.    type_short    = 0b000000001000,
  11.    type_ushort   = 0b000000010000,
  12.    type_int      = 0b000000100000,
  13.    type_uint     = 0b000001000000,
  14.    type_llong    = 0b000010000000,
  15.    type_ullong   = 0b000100000000,
  16.    type_float    = 0b001000000000,
  17.    type_double   = 0b010000000000,
  18.    type_ldouble  = 0b100000000000,
  19.  
  20.    /**    OTHER    **/
  21.    type_signed   = 0b111010101011,
  22.    type_unsigned = 0b000101010100,
  23.    type_all      = 0b111111111111
  24. };
  25.  
  26. bool allNumeric(string s){
  27.    for(int i=0; i<s.size(); i++)
  28.        if(s[i]<48 || s[i]>57)
  29.        return false;
  30.    return true;
  31. }
  32.  
  33. bool minorEqual(string a, string b){
  34.    if(a.size()<b.size()) return true;
  35.    if(a.size()>b.size()) return false;
  36.    if(a==b) return true;
  37.    for(int i=0; i<a.size(); i++)
  38.        if(a[i]<b[i]) return true;
  39.        else if(a[i]>b[i]) return false;
  40.    return true;
  41. }
  42.  
  43. int typeOf(string s){
  44.    if(s=="") return 0;
  45.    int type = 0;
  46.    bool sign = false;
  47.    /** BOOL **/
  48.    if((s.size()==1 && (s[0]=='0'||s[0]=='1'))||(s.size()==4 &&s.substr(0, 4)=="true")||(s.size()==5 &&s.substr(0, 5)=="false"))
  49.        type+=type_bool;
  50.  
  51.    /** CHAR && UCHAR **/
  52.    if(s.size()==1)
  53.        type+=type_char+type_uchar;
  54.    else{
  55.        if(s[0]=='-')
  56.            sign=true;
  57.        if(s.size()<4+sign && allNumeric(s.substr(sign, s.size()))){
  58.            if(sign){
  59.                if(minorEqual(s.substr(1, s.size()), "128"))
  60.                    type+=type_char;
  61.            }else{
  62.                if(minorEqual(s.substr(0, s.size()), "127"))
  63.                    type+=type_char;
  64.                if(minorEqual(s.substr(0, s.size()), "255"))
  65.                    type+=type_uchar;
  66.            }
  67.        }
  68.    }
  69.  
  70.    /** SHORT && USHORT **/
  71.    if(s[0]=='-')
  72.        sign=true;
  73.    if(allNumeric(s.substr(sign, s.size()))){
  74.        if(sign){
  75.            if(minorEqual(s.substr(1, s.size()), "32768"))
  76.                type+=type_short;
  77.        }else{
  78.            if(minorEqual(s.substr(0, s.size()), "32767"))
  79.                type+=type_short;
  80.            if(minorEqual(s.substr(0, s.size()), "65535"))
  81.                type+=type_ushort;
  82.        }
  83.    }
  84.  
  85.    /** INT && UINT **/
  86.    if(s[0]=='-')
  87.        sign=true;
  88.    if(allNumeric(s.substr(sign, s.size()))){
  89.        if(sign){
  90.            if(minorEqual(s.substr(1, s.size()), "2147483648"))
  91.                type+=type_int;
  92.        }else{
  93.            if(minorEqual(s.substr(0, s.size()), "2147483647"))
  94.                type+=type_int;
  95.            if(minorEqual(s.substr(0, s.size()), "4294967295"))
  96.                type+=type_uint;
  97.        }
  98.    }
  99.  
  100.    /** LONG && ULONG **/
  101.    if(s[0]=='-')
  102.        sign=true;
  103.    if(allNumeric(s.substr(sign, s.size()))){
  104.        if(sign){
  105.            if(minorEqual(s.substr(1, s.size()), "9223372036854775808"))
  106.                type+=type_llong;
  107.        }else{
  108.            if(minorEqual(s.substr(0, s.size()), "9223372036854775807"))
  109.                type+=type_llong;
  110.            if(minorEqual(s.substr(0, s.size()), "18446744073709551615"))
  111.                type+=type_ullong;
  112.        }
  113.    }
  114.    double b=atof(s.c_str());
  115.    float a=(float)b;
  116.    bool is=false;
  117.    if(b==0.0 && (s=="0"||s=="0.0")){
  118.        type+=type_float+type_double;
  119.    }else if(b!=0.0){
  120.        type+=type_double;
  121.        if(a==b)
  122.            type+=type_float;
  123.    }
  124.    return type;
  125. }
  126.  
  127. int main(){
  128.    string s;
  129.    getline(cin, s);
  130.    if(typeOf(s)&type_int)
  131.        cout << "Se puede transformar en un entero (signed)." << endl;
  132.    cin.get();
  133.    return 0;
  134. }


Ejemplo de como transformar string a int:
Código
  1. int potencia(int n, int b){
  2.   int temp=1;
  3.   for(int i=0;i<b;i++) temp=temp*n;
  4.   return temp;
  5. }
  6.  
  7. int parseString(string s){
  8. string a;
  9. int num = 0;
  10. for(int i=s.length()-1;i>=0;i--){
  11.  if(!((int)s[i]>=48 && (int)s[i]<=57)) return 0;
  12.  num+=((int)s[i]-48)*(potencia(10, s.length()-i-1));
  13. }
  14. return num;
  15. }

Bueno, aún no acabé con las funciones para transformar de string a numérico.
Igualmente, puedes usar las funciones atol(string) Retorna un LONG, atof() Retorna un DOUBLE, atoi() Retorna un INT


EDITO: Me olvidé decir, que el FLOAT, de la función typeOf(string), no funciona. Pero funciona para double.


« Última modificación: 8 Febrero 2014, 21:50 pm por ivancea96 » En línea

minari02

Desconectado Desconectado

Mensajes: 26


Ver Perfil
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #11 en: 9 Febrero 2014, 15:04 pm »

mmm... ahora entiendo... Muchas gracias a todos  ;D


En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #12 en: 9 Febrero 2014, 18:22 pm »

Interesante la solución de minari!!!

Como lo que se introduce es una cadena, un programa personalizado podría decidir si se intentó introducir un short, int, long, float, etc. Al estilo quizá de VisualBasic.

Aunque yo sólo añadiría que en el código se usan algunas características C++ no indispensables, uno podría intentar ---como ejercicio---, traducir todo a C puro. Porque si no es esencial usar clases, ¿por qué C++ u no C?

De hecho, leí una vez que supuestamente el código compilado "tipo C" se ejecuta más rápida y eficientemente que el código compilado como "tipo C++". ¿Qué saben de esto?
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
minari02

Desconectado Desconectado

Mensajes: 26


Ver Perfil
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #13 en: 9 Febrero 2014, 20:21 pm »

me parece muy interesante... aunque, complicado! yoel_alejandro en el titulo he especificado C++ porque es el que estoy aprendiendo pero teniendo lo que  ivancea96 si sabes C puedes pasarlo de C++ a C supongo yo...
En línea

vangodp


Desconectado Desconectado

Mensajes: 455



Ver Perfil
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #14 en: 9 Febrero 2014, 20:30 pm »

C es lineal, c++ pega muchos mas saltos.
C también se desvía cuando creas funciones no inline, pero a cambio un programa en c++ puede ser un plato de macarrón. XD
La programación orientada a objetos pasa mayor factura.
Pero siempre puedes optimizar lo máximo :D
Si haces un programa que no salte de una función a otra esta claro que va ser mas eficiente.


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #15 en: 10 Febrero 2014, 18:41 pm »

Si por ejemplo declaras:
Código
  1. int x;

y luego haces algo como
Código
  1. scanf( "%d", &x);

pues ya dijiste que se esperaba un tipo entero. No importa que el usuario meta un valor decimal a través del teclado, el valor será convertido forzosamente a un entero (según las reglas implícitas de conversión de C).
No hay que confundir los temas porque se corre el riesgo de terminar con una confusión espantosa.

Las conversiones (promoción de enteros y conversiones aritméticas usuales) se realizan tomando un tipo compatible y pasando este a otro. Por ejemplo "(unsigned int) - 1" resulta en el valor máximo que puede almacenarse en una variable de tipo unsigned int.

En el caso que nos ocupa (obtener un valor en base a una cadena de caracteres) lo único que aplica es la definición de la función utilizada ya sea atoi, strtol, scanf, etc..

----

No se puede!!. C es un lenguaje "tipado", al contrario de otros lenguajes donde una variable puede alegremente cambiar de un tipo a otro.

Como te contestó otro usuario, esto significa que a cada variable que uses en C debes haberle definido previamente un tipo, de lo contrario el compilador te informará un error.

+

* Eso de que informa del error suena a broma. ¡Ojalá fuese siempre así!.

* Aunque previamente se haya definido un tipo para una variable siempre existe la posibilidad de cambiar el tipo mediante el correspondiente casting o mediante el uso de funciones tipo atoi, itoa,atof, etc.
Aqui se están mezclando dos temas:

A) Obtener el valor de una variable de tipo T y convertir ese valor a otro tipo U mediante una conversión explicita o implícita. Esto aplica a C.

B) Lenguajes sin tipos donde las operaciones dependen del contexto, esto usualmente aplica con lenguajes de scripts, mas o menos así:
Código:
a = 111         // Valor numerico 111
b = 222         // Valor numerico 222
Imprimir a + b  // Imprime 333

// ...

a = "111"       // La cadena 111
b = "222"       // La cadena 222
Imprimir a + b  // Imprime 111222

Para que veas minari02 como funciona, observa la salida del código que te propongo como validación de un int en el que no admite cosas como 1.23, 12as, asd12, o un simple caracter. Ante tales situaciones te vuelve a pedir que introduzcas un int:
Ya que la validación consiste en verificar que los caracteres sean solo dígitos el bucle lo puedes acortar a:
Código
  1. do {
  2.   puts("Introduzca un numero entero:");
  3.   scanf("%s", num);
  4.  
  5.   for (i = 0; isdigit(num[i]); i++)
  6.      ;
  7. }while (num[i] != '\0');
Y falta incluir el encabezado <stdlib.h> antes de utilizar atoi. Por ultimo como validación ambos programas (el tuyo y el mio) solo sirven para practicar ya que tienen agujeros (por ejemplo no se verifica el valor de retorno de la función scanf).

----

Yo uso gcc de GNU para Linux y siempre me informa esta situación y lo cataloga como error (no Warning). Ello significa que el proceso de compilación se detiene y no genera un ejecutable. Por ejemplo, quise poner la sentencia de asignación x = 1 sin antes haber declarado la x y aquí el mensaje obtenido:
Código:
test1.c: In function ‘main’:
test1.c:18: error: ‘x’ undeclared (first use in this function)
test1.c:18: error: (Each undeclared identifier is reported only once
test1.c:18: error: for each function it appears in.)

Ni siquiera (considerando que C99 define "int por defecto") se le ocurrió tomar la variable x como int y seguir con la compilación.
Es al revés. En el estándar C90 si se declara una variable y se omite el tipo este es, de forma predeterminada, int. A partir de C99 no indicar el tipo en una declaración es un error.

Por otra parte, respecto a lo de convertir "1.23" en 1, y "12as" como 12, a eso precisamente me refiero con "las reglas de conversión implícita de tipo de C". Ya que es un lenguaje tipado, él posee protolocos internos que le dicen cómo convertir un valor dado a otro tipo esperado.
Sin ofender y sin temor a repetir: las conversiones de tipos compatibles no aplican en este caso, lo único que aplica es la especificación de la función utilizada.

Un saludo
En línea

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
Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #16 en: 10 Febrero 2014, 20:55 pm »

Sólo para comentar, considérese que la propuesta:

Código
  1.    do {
  2.      puts("Introduzca un numero entero:");
  3.      scanf("%s", num);
  4.  
  5.      for (i = 0; isdigit(num[i]); i++)
  6.         ;
  7.    }while (num[i] != '\0');
  8.  
no admite números negativos. Los números "negativos" también son enteros. Y por cierto que isdigit requiere <ctype.h> !!!

Y un poco aparte del tema, moderador una pregunta, ¿Hay alguna manera que solicitar que mis mensajes no sea citados o mencionados por cierto usuario en particular? Porque en este foro hay gente que en vez de venir a aportar soluciones propias, se dedica a examinar y poner epítetos a los aportes de los demás.
« Última modificación: 10 Febrero 2014, 21:07 pm por yoel_alejandro » En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Programa que identifique que tipo de dato se introduce C++
« Respuesta #17 en: 11 Febrero 2014, 02:48 am »

Sólo para comentar, considérese que la propuesta:
Código
  1.    do {
  2.      puts("Introduzca un numero entero:");
  3.      scanf("%s", num);
  4.  
  5.      for (i = 0; isdigit(num[i]); i++)
  6.         ;
  7.    }while (num[i] != '\0');
no admite números negativos. Los números "negativos" también son enteros.
Por supuesto que no los procesa ya que como comente el programa de leosansan solo intenta validar verificando que todos los caracteres sean dígitos.

Y por cierto que isdigit requiere <ctype.h>!
Ouch! Gracias por la corrección.

Un saludo
En línea

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
Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Error tipo de dato.
Bases de Datos
usuani 2 7,820 Último mensaje 16 Febrero 2010, 15:17 pm
por usuani
Recomendación tipo de dato
Bases de Datos
novalida 2 3,196 Último mensaje 4 Diciembre 2010, 04:06 am
por [D4N93R]
Problema con tipo de dato de una variable
Programación C/C++
Blackhawk222 1 2,380 Último mensaje 12 Febrero 2011, 17:14 pm
por Ca0s
Función con parametro sin tipo de dato
.NET (C#, VB.NET, ASP)
Shell Root 5 3,343 Último mensaje 16 Septiembre 2012, 19:46 pm
por Novlucker
Programa identifique partes de una linea
Programación C/C++
m@o_614 5 2,852 Último mensaje 28 Diciembre 2013, 10:14 am
por leosansan
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines