Autor
|
Tema: Programa que identifique que tipo de dato se introduce C++ (Leído 15,732 veces)
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
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:#include <iostream> using namespace std; enum type{ /** TYPES **/ type_bool = 0b000000000001, type_char = 0b000000000010, type_uchar = 0b000000000100, type_short = 0b000000001000, type_ushort = 0b000000010000, type_int = 0b000000100000, type_uint = 0b000001000000, type_llong = 0b000010000000, type_ullong = 0b000100000000, type_float = 0b001000000000, type_double = 0b010000000000, type_ldouble = 0b100000000000, /** OTHER **/ type_signed = 0b111010101011, type_unsigned = 0b000101010100, type_all = 0b111111111111 }; bool allNumeric(string s){ for(int i=0; i<s.size(); i++) if(s[i]<48 || s[i]>57) return false; return true; } bool minorEqual(string a, string b){ if(a.size()<b.size()) return true; if(a.size()>b.size()) return false; if(a==b) return true; for(int i=0; i<a.size(); i++) if(a[i]<b[i]) return true; else if(a[i]>b[i]) return false; return true; } int typeOf(string s){ if(s=="") return 0; int type = 0; bool sign = false; /** BOOL **/ 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")) type+=type_bool; /** CHAR && UCHAR **/ if(s.size()==1) type+=type_char+type_uchar; else{ if(s[0]=='-') sign=true; if(s.size()<4+sign && allNumeric(s.substr(sign, s.size()))){ if(sign){ if(minorEqual(s.substr(1, s.size()), "128")) type+=type_char; }else{ if(minorEqual(s.substr(0, s.size()), "127")) type+=type_char; if(minorEqual(s.substr(0, s.size()), "255")) type+=type_uchar; } } } /** SHORT && USHORT **/ if(s[0]=='-') sign=true; if(allNumeric(s.substr(sign, s.size()))){ if(sign){ if(minorEqual(s.substr(1, s.size()), "32768")) type+=type_short; }else{ if(minorEqual(s.substr(0, s.size()), "32767")) type+=type_short; if(minorEqual(s.substr(0, s.size()), "65535")) type+=type_ushort; } } /** INT && UINT **/ if(s[0]=='-') sign=true; if(allNumeric(s.substr(sign, s.size()))){ if(sign){ if(minorEqual(s.substr(1, s.size()), "2147483648")) type+=type_int; }else{ if(minorEqual(s.substr(0, s.size()), "2147483647")) type+=type_int; if(minorEqual(s.substr(0, s.size()), "4294967295")) type+=type_uint; } } /** LONG && ULONG **/ if(s[0]=='-') sign=true; if(allNumeric(s.substr(sign, s.size()))){ if(sign){ if(minorEqual(s.substr(1, s.size()), "9223372036854775808")) type+=type_llong; }else{ if(minorEqual(s.substr(0, s.size()), "9223372036854775807")) type+=type_llong; if(minorEqual(s.substr(0, s.size()), "18446744073709551615")) type+=type_ullong; } } double b=atof(s.c_str()); float a=(float)b; bool is=false; if(b==0.0 && (s=="0"||s=="0.0")){ type+=type_float+type_double; }else if(b!=0.0){ type+=type_double; if(a==b) type+=type_float; } return type; } int main(){ string s; getline(cin, s); if(typeOf(s)&type_int) cout << "Se puede transformar en un entero (signed)." << endl; cin.get(); return 0; }
Ejemplo de como transformar string a int:int potencia(int n, int b){ int temp=1; for(int i=0;i<b;i++) temp=temp*n; return temp; } int parseString(string s){ string a; int num = 0; for(int i=s.length()-1;i>=0;i--){ if(!((int)s[i]>=48 && (int)s[i]<=57)) return 0; num+=((int)s[i]-48)*(potencia(10, s.length()-i-1)); } return num; }
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 INTEDITO: 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
Mensajes: 26
|
mmm... ahora entiendo... Muchas gracias a todos
|
|
|
En línea
|
|
|
|
Yoel Alejandro
|
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
Mensajes: 26
|
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
Mensajes: 455
|
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 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
Mensajes: 1.639
|
Si por ejemplo declaras: int x;
y luego haces algo como 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í: 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: do { puts("Introduzca un numero entero:"); ; }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: 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
|
Sólo para comentar, considérese que la propuesta: do { puts("Introduzca un numero entero:"); scanf("%s", num); for (i = 0; isdigit(num[i]); i++) ; }while (num[i] != '\0');
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
Mensajes: 1.639
|
Sólo para comentar, considérese que la propuesta: do { puts("Introduzca un numero entero:"); scanf("%s", num); for (i = 0; isdigit(num[i]); i++) ; }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
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Error tipo de dato.
Bases de Datos
|
usuani
|
2
|
7,820
|
16 Febrero 2010, 15:17 pm
por usuani
|
|
|
Recomendación tipo de dato
Bases de Datos
|
novalida
|
2
|
3,196
|
4 Diciembre 2010, 04:06 am
por [D4N93R]
|
|
|
Problema con tipo de dato de una variable
Programación C/C++
|
Blackhawk222
|
1
|
2,380
|
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
|
16 Septiembre 2012, 19:46 pm
por Novlucker
|
|
|
Programa identifique partes de una linea
Programación C/C++
|
m@o_614
|
5
|
2,852
|
28 Diciembre 2013, 10:14 am
por leosansan
|
|