String vs Char Array
La cuestión que aquí nos concierne es que los tipos de datos no solamente se pueden presentar como números sino como letras.
En este modelo podemos deducir que los algoritmos de ordenamiento anteriores ya no son válidos, puesto que no tratamos con estos números si no con letras como un conjunto de datos ordenados para formar una palabra.
Podemos considerar entonces dos formatos para manipulación de letras.
- El objeto String
- Un array de caracteres
Char Array
Para empezar a explicar este modelo, debemos considerar que las letras, siguen siendo un valor numérico que se traduce a letras mediante el código ASCII y a los que se corresponde su valor a una representación gráfica mediante este estándar.
Un char array es entonces un array en el que almacenaremos un conjunto de letras para crear palabras completas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | int ZMS_intarray[] ={ 90, 77, 83}; char ZMS_chararray[] ={ 'Z' , 'M' , 'S' }; void setup() { Serial.begin(9600); Serial.println( "Int array: " ); for ( int i = 0; i < 3 ; i++ ){ Serial.print( ZMS_intarray[i] ); } Serial.println(); Serial.println( "Char array: " ); for ( int i = 0; i < 3 ; i++ ){ Serial.print( ZMS_chararray[i] ); } Serial.println(); Serial.println( "Convert int to char: " ); for ( int i = 0; i < 3 ; i++ ){ Serial.print( ( char )ZMS_intarray[i] ); } } void loop() { } |
Contador de letras
Imaginemos que queremos contar todas las letras de un texto y almacenarlas dentro de otro array en el que iremos contando cuántas veces se repiten las letras.
El truco de este ejercicio es acceder a la posición del array del contador en base a la letra que hemos seleccionado. De esta forma simplificamos el cálculo integrándolo en un bucle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | int counter[255]; void initCounter(){ for ( int i =0; i < sizeof (text_array)/ sizeof ( char ); i++){ text_array[i] = ' ' ; } for ( int i =0; i < 255; i++){ counter[i] = 0 ; } }; void setup() { Serial.begin(9600); Serial.println(text_array); for ( int i =0; i < sizeof (text_array)/ sizeof ( char ); i++){ counter[ ( int )text_array[i] ]++; } for ( int i =97; i < 122; i++){ Serial.print( ( char )i ); Serial.print( " : " ); Serial.println( counter[i] ); } initCounter(); } void loop() { if (Serial.available()){ String text = Serial.readString(); text.toCharArray( text_array,text.length() ); Serial.println( text_array ); for ( int i =0; i < sizeof (text_array)/ sizeof ( char ); i++){ counter[ ( int )text_array[i] ]++; } for ( int i =97; i < 122; i++){ Serial.print( ( char )i ); Serial.print( " : " ); Serial.println( counter[i] ); } initCounter(); } } |
Para visualizar el resultado solamente nos interesará observar las letras que se asocian a las letras minúsculas. Por ello, solamente hacemos un repaso en bucle desde el número 97 al número 122.
String
Los arrays de caracteres son útiles para ahorrar espacio en memoria de nuestra placa, pero para manipulación puede ser un verdadero infierno.
Para ello, podemos declarar nuestros textos como objetos de la clase String y usar los métodos de búsqueda que ya vienen definidos por defecto, como los siguientes.
- indexOf
- length
- remove
- replace
- substring
- toInt
- trim
- StartsWith – EndsWith
- toLowerCase – to UpperCase
- toCharArray
Para usar estas funcionalidades proponemos el siguiente ejercicio.
- La linea contiene dos números que debemos leer
- El mensaje contiene un carácter de entrada * y un carácter de salida # que verificar que es un mensaje válido
- Los dos números deben estar separados por una coma.
Para realizar este programar en lugar de usar un array de caracteres, manejaremos de una forma fácil e intuitiva el modelo String.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | String texto; int num1; int num2; void setup() { Serial.begin(9600); texto = (String)( "*123,45#" ); num1 = ( int )(0); num2 = ( int )(0); } void loop() { if (Serial.available()) { texto = (Serial.readString()); texto.trim(); if ((texto.startsWith( "*" )) && (texto.endsWith( "#" ))) { texto.replace( "*" , "" ); texto.replace( "#" , "" ); num1 = (texto.toInt()); Serial.println(num1); texto. remove (0,((texto.indexOf( "," )) + 1)); num2 = (texto.toInt()); Serial.println(num2); } } } |
Para usarlo, solo tendremos que abrir el monitor serie y enviar la linea de datos para realizar la lectura y procesamiento de los datos.
Si no nos funciona el envío de datos, recordemos que tenemos que seleccionar Sin ajuste de linea, ya que seleccionar ambos NL & CR, envían carácteres ASCII de control asociados a esas acciones.
Los ejercicios de código, proyectos y recursos que desarrollaremos durante el curso se pueden consultar a través de nuestro Github.