Una de las funcionalidades más pobres, peor implementadas, y con menor documentación de robotC es el manejo de ficheros. El manejo de ficheros es una herramienta muy útil que nos puede servir para guardar información y usarla con otros programas, independientemente de su lenguaje de programación. Por tanto es la universalidad de los ficheros la que nos permitiría comunicar robotC con otro programa de cualquier lenguaje. Sin embargo los creadores de robotC no vieron está utilidad cómo algo importante, y por tanto no han implementado la funcionalidad necesaria para el correcto manejo de ficheros.
Manejo de ficheros en robotC: Apertura y cierre
Antes de poder operar con un fichero es necesario abrirlo. En la mayoria de lenguajes de programación hay dos modos de apertura, modo lectura y modo escritura. Abrimos en modo lectura si queremos leer la información que hay en el archivo, sin modificarlo. Abrimos en modo escritura si queremos escribir en el archivo, modificando su contenido.
OpenRead(fichero, error, nombre_fichero, tamaño_fichero) : Abre el fichero con el nombre indicado en modo lectura. En tamaño_fichero tenemos que indicar el tamaño del fichero. La variable error será distinta de 0 si ha habido algún error a la hora de abrir el fichero. A partir de que este abierto trabajaremos con el fichero usando el nombre que le hayamos dado a la variable fichero.
Nota: La variable fichero es de tipo TFileHandle, y la variable error es de tipo TFileIOResult.
OpenWrite(fichero, error, nombre_fichero, tamaño_fichero) : En este caso se abre el fichero en modo escritura. En caso de que el fichero no exista se crea automáticamente, y si existe se borra su contenido antes de empezar a escribir.
Close(fichero, error) : Cierra el fichero. Como siempre la variable error nos indicará si ha habido algún problema, en este caso a la hora de cerrar el fichero.
Es muy importante cerrar los ficheros cuando hemos acabado de usarlos, o podrían generar errores la próxima vez que queramos utilizarlos.
Lectura de ficheros en robotC:
En RobotC hay diversas funciones para leer de ficheros, se diferencian principalmente en el tipo de dato que leen. Para que la lectura sea correcta el dato tiene que haber sido escrito con el mismo tipo que vamos a leer. El principal problema de RobotC es que no tiene capacidad de leer strings, lo que es un gran problema a la hora de tratar de leer archivos con strings. Las funciones para leer de archivos en RobotC son las siguientes:
ReadByte(fichero, error, nParm): Lee una variable tipo byte (8-bit) del fichero especificado. El valor de la variable error es distinto de cero si ocurre algún error de lectura.
ReadFloat(fichero, error, fParm): Lee una variable tipo float del fichero especificado. El valor de la variable error es distinto de cero si ocurre algún error de lectura.
ReadLong(fichero, error, nParm): Lee una variable tipo long (32-bit) del fichero especificado. El valor de la variableerror es distinto de cero si ocurre algún error de lectura.
ReadShort(fichero, nIoResult, nParm): Lee una variable tipo short(16-bit) del fichero especificado. El valor de la variableerror es distinto de cero si ocurre algún error de lectura.
Estas funciones solo nos servirán a la hora de leer variables que hayamos escrito con la función de escritura correspondiente que escriba el mismo tipo de dato en el fichero. Hay que ser muy cuidadoso a la hora de escribir ficheros en otros lenguajes de programación para que los lea robotC, ya que muchas veces no funcionará. Los más compatibles serán lógicamente C y C++.
Escritura de ficheros en robotC:
Al contrario que con la lectura, sí se pueden escribir ficheros con strings, lo cuál nos ayudará bastante a la hora de usar datos capturados por robotC con otro programa (por ejemplo dibujar gráficas con el gnuplot). Otros tipos de datos escritos por robotC pueden ser leídos por robotC con la función de lectura correspondiente, o por otros lenguajes de programación. Las funciones para la escritura en ficheros en robotC son:
WriteByte(fichero, error, nParm): Escribe un byte en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
WriteFloat(fichero, error, fParm): Escribe un float en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
WriteLong(fichero, error, nParm): Escribe un long (32-bit) en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
WriteShort(fichero, error, nParm): Escribe un short (16-bit) en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
WriteString(fichero, error, sParm): Escribe una cadena de texto con el terminador null en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
WriteText(fichero, error, sParm): Escribe una cadena de texto sin el terminador null en el fichero especificado. El valor de la variable error es distinto de cero cuando existe algún error de escritura.
La escritura de ficheros en RobotC esta más desarrollada que la lectura, lo que potencia la compatibilidad e itercambio de datos con otros programas. Aún así es curioso que el manejo de ficheros en RobotC sea más limitado que en NXT-G, cuando NXT-G debería ser mucho más limitado en este aspecto.
¿Qué escribe RobotC en los ficheros?:
Para ver qué escribe robotC en los ficheros hemos hecho unas pruebas: escribimos ficheros con las distintas funciones de robotC, y luego vemos su contenido con un editor hexadecimal. Los resultados son los siguientes:
WriteByte(fichero, error, (byte) “a”):
Veamos cómo efectivamente escribe un byte (8 bits)
WriteFloat(fichero, error, (float) 17.0):
Vemos que los float ocupan unos 32 bits (4 bytes).
WriteFloat(fichero, error, (float) 1.5):
WriteFloat(fichero, error, (float) 1.5):
Entre float y float no se escribe ningún byte, sino que van seguidos. A la hora de leerlos simplemente se leerán 32 bits y se interpretarán. Esto sucede también con todos los demás tipos de escritura.
WriteLong(fichero, error, (long) 17):
Los long también se componen de 32 bits como vimos en su definición.
WriteShort(fichero, error, (short) 17):
Así como los short se componen de solo 16 bits (la mitad).
WriteString(fichero, error,“hola”):
Se escribe hola, a byte por carácter, añadiendo el null al final (el byte 00).
WriteText(fichero, error, “hola”):
Aquí podemos ver cómo WriteText no escribe el carácter null al final de cada cadena de texto.
Cómo escribir ficheros en C++ para leerlos en robotC:
Para escribir datos en un fichero de tipo float, long … necesitaremos crear un archivo de tipo binario. Luego necesitaremos escribir en dicho fichero haciendo un casting especial, indicando el tipo de archivo que vamos a escribir, y su tamaño. Por último cerraremos el fichero. El código que escribe un float en un fichero binario capaz de ser leído por robotC sería así:
float numero = 10;
ofstream fsalida("numero.dat", ofstream::out | ios::binary);
fsalida.write(reinterpret_cast<char *>(&numero), sizeof(numero));
fsalida.close();
Espero que os haya gustado el artículo, ante cualquier duda podéis preguntar en el foro, que para eso estamos.
P.D.: Este artículo hace referencia a la versión 2.02 de robotC, la versión más actualizada a fecha de publicación de este artículo.