| Versión 3.0 |
| 800x600 mínimo |
|
En esta lección: El archivo stdio.h ----- Entrada numerica ----- Entrada de cadenas ----- Entrada/Salida en memoria ----- Otras secciones: Conceptos básicos ----- Programando en C ----- Programando en C++ ----- Programando Windows 9x. ----- Teoría electrónica ----- Circuitos electrónicos ----- Actividades adicionales ----- Hipervínculos ----- Contácteme: Dudas y comentarios ----- |
El archivo de cabecera stdio.hCuando nos referimos a entrada/salida estándar (E/S estándar) queremos decir que los datos o bien se están leyendo del teclado, ó bien se están escribiendo en el monitor de video. Como se utilizan muy frecuentemente se consideran como los dispositivos de E/S por default y no necesitan ser nombrados en las instrucciones de E/S. Esto le quedará claro a lo largo de este capítulo. El primer código es el siguiente:
La primera cosa por estudiar la tenemos en la primera línea. La instrucción #include <stdio.h> es muy parecida a la instrucción #define que ya hemos estudiado excepto que en lugar de una simple sustitución se lee todo un archivo en este punto. El sistema encontrará el archivo llamado stdio.h y leerá la totalidad del contenido reemplazando la instrucción #include stdio.h. Obviamente el archivo debe contener enunciados válidos de C que pueden ser compilados como parte del programa. Este archivo en particular contiene varias definiciones y prototipos para las operaciones de E/S estándar. El archivo es llamado archivo de cabecera y su compilador incluye una gran variedad de ellos, cada uno con un propósito específico y cualquiera de ellos puede ser incluido en cualquier programa. El compilador C utiliza el símbolo de doble comilla para indicar que la búsqueda del archivo include empieza en el directorio actual de trabajo, y si no se encuentra ahí, la búsqueda continuará en el directorio include tal y como está especificado en el ambiente de su compilador. Además se utilizan los símbolos de "menor que" y "mayor que" para indicar que la búsqueda empieza directamente en el directorio include del compilador. Se pueden utilizar tantos include como sea necesario, y es perfectamente válido que un archivo de cabecera incluya uno o más archivos de cabecera adicionales. Comprenderá a su vez que cuando escriba programas largos, es posible incluir ciertas rutinas comunes en un archivo de cabecera e incluir el mismo como ya se ha descrito. Continuando con el código de ejemplo. Se define la variable llamada c y se despliega un mensaje en pantalla con la yá conocida función printf ( ), entramos en un bucle que no termina sino hasta que el caracter introducido sea una X mayúscula, dentro del bucle nos encontramos con dos nuevas funciones, una que sirve para leer un caracter desde el teclado y otra que despliega dicho caracter en pantalla. La función getchar ( ) lee un solo caracter desde el dispositivo estándar de entrada, o sea, el teclado, y lo asigna a la variable llamada c. La siguiente función llamada putchar ( ) utiliza el dispositivo de salida estándar, es decir, el monitor de video, para desplegar el caracter contenido en c. El caracter se despliega en la posición actual del cursor y éste avanza un espacio para el siguiente caracter, por lo tanto el sistema se ocupa del orden de despliegue de los caracteres. Compile y ejecute este programa para descubrir algunas características adicionales, como el hecho que conforme escriba en el teclado, lo escrito se despliega en el monitor y al presionar la tecla enter se repite la línea completa de texto, tal parece que memoriza los caracteres y luego los vuelve a deplegar. El sistema operativo a nuestra ayudaEs conveniente dar una breve explicación de cómo trabaja el sistema operativo para entender lo que pasa. Cuando se leen datos desde el teclado bajo el control del sistema operativo, los caracteres se almacenan en un buffer (segmento de memoria RAM temporal) hasta que se introduce un retorno de carro momento en el cual la totalidad de los caracteres se devuelven al programa. Cuando se teclean los caracteres, éstos son mostrados en pantalla uno a la vez. A ésto se le llama eco, y sucedeo en muchas de las aplicaciones que Usted corre en su computadora. Para demostrar lo dicho en el programa anterior, teclee una serie continua de caracteres tal que contenga una X mayúscula, verá que conforme vaya tecleando la 'X' aparece en pantalla, pero una vez que presiona la tecla enter, la llegar la cadena de caracteres al punto donde se encuentra la 'X', ahí termina el programa, lo que sucede es que al presionar la tecla enter se entrega al programa la cadena de caracteres, como el programa señala su fin al encontrar una X mayúscula, los caracteres escritos después de la 'X' no se despliegan en pantalla. Veamos otro código:
Nuevamente empezamos con el archivo de E/S estándar de cabecera, luego definimos una variable llamada c e imprimimos un mensaje de bienvenida. Como en el programa anterior, entramos en un bucle y lo ejecutamos hasta encontrar una X mayúscula, pero la acción es un poco diferente, observe la inclusión del archivo conio.h y de la función _getch ( ) mismos que no forman parte del estándar ANSI-C pero que están disponibles en la mayoría de los compiladores escritos para DOS. La función llamada _getch ( ) es una función para obtener un caracter que difiere de la función getchar ( ) en que no depende de DOS. Ësta función lee un caracter sin hacer eco en pantalla entregando el caracter inmediatamente al programa. Tenga en cuenta que la función _getch ( ) no está incluida en el estándar ANSI-C y por lo tanto puede no estar disponible en todos los compiladores, además utilizar ésta función puede hacer el progama menos portable a otras máquinas, si su compilador soporta la función, compile este programa y observe su funcionamiento comparado con el programa anterior, verá que al presionar la tecla enter no coloca una nueva línea con el retorno de carro, para corregir esta situación tenemos el siguiente programa:
Tenemos dos nuevos enunciados que definen los códigos de caracter para la nueva línea (linefeed en inglés, traducido en este programa como "alimentar línea", AL), y para el retorno de carro (carriage return, "retorno de carro", RC), si Usted consulta una tabla de códigos ASCII verá por qué éstos términos se han definido como 10 y 13. En el programa principal, después de desplegar el caracter introducido en pantalla lo comparamos con RC, y si es igual además desplegamos una nueva línea, AL. En los programas presentados hasta este momento no hemos puesto, como es usual en este curso, las pantallas que demuestran la salida del programa, esto se debe al hecho de que los programas de este capítulo depende su salida enteramente de lo que Usted teclee, por lo que le recomiendo ampliamente la compilación y ejecución de cada programa de ejemplo para un mejor entendimiento de la mecánica de las funciones aquí presentadas. Le toca ahora el turno a los números enteros. Entrada numéricaEstudie el siguiente programa:
La mecánica del programa es bastante similar a lo que hemos estado trabajando, excepto que definimos una variable de tipo int llamada numero y el bucle continua hasta que el valor introducido sea 100. En lugar de leer un solo caracter tal y como lo hemos hecho en los programas anteriores, ahora leemos un número completo con una sola llamada a la función llamada scanf ( ), esta función es muy similar a la conocida printf ( ) solo que se utiliza para introducir datos en lugar de desplegarlos. Observe en la línea donde se encuentra la función scanf ( ) que ésta no refiere directamente a la variable llamada numero, en lugar de esto, utiliza la dirección de la misma (o sea, un puntero a la variable), ya que espera le sea retornado un valor. La función scanf ( ) busca en la línea de entrada hasta encontrar el primer campo de datos, lee los caracteres enteros hasta encontrar un espacio en blanco ó un caracter decimal inválido, en este punto detiene la lectura y retorna el valor encontrado. Si su sistema utiliza enteros de 2 bytes y Usted introduce un número hasta 32767 inclusive éste se despliega correctamente, pero con números mayores parece haber un error. Por ejemplo, si Usted introduce 32768 se despliega -32768, e introduciendo 65536 el valor desplegado es cero. La explicación de éste fenómeno está en la manera en que está definido una variable de tipo int, el bit más significativo para un patrón disponible de 16 bits para una variable entera es el bit de signo por lo que sólo nos quedan 15 bits para representar el valor, por lo tanto la variable sólo puede tomar valores comprendidos entre -32768 y 32767. Este detalle debe tomarlo en cuenta al momento de hacer sus programas. Lo dicho es válido sólo para los compiladores de 16 bits, aunque existe la cada vez mayor posibilidad de que su compilador utilice valores enteros almacenados en campos mayores de 16 bits, en este caso se aplican los mismos principios excepto que el rango de valores es mayor. Compile y ejecute el programa anterior y experimente con lo anteriormente dicho. Entrada de cadenasAhora veremos cómo introducir una cadena de caracteres en nuestro siguiente programa, el código es el siguiente:
Este programa es similar al último código que estudiamos, excepto que en lugar de definir una variable de tipo int, definimos una variable de tipo string con un límite de 24 caracteres (recuerde que las cadenas de caracteres deben incluir un caracter nulo al final de la cadena). La variable en la función scanf ( ) no requiere un símbolo de & porque cadena es un array y por definición incluye un puntero. Este programa no requiere mayor explicación. Entrada/Salida en memoriaHablemos ahora de otro tipo de E/S, uno que no tiene salida al mundo exterior pero que permanece en la computadora, el código es este:
En este programa definimos algunas variables, después asignamos algunos valores a las llamadas numeros para propósitos de ilustración y entonces utilizamos la función sprintf ( ), ésta actúa similar a la función printf ( ) pero en lugar de desplegar los datos a un dispositivo de salida, imprime la cadena formateada en una cadena en memoria. En este caso la cadena vá a la variable llamada linea, porque esta es la cadena que introducimos como primer argumento de la función sprintf ( ). Como la cadena generada continúa en memoria, podemos leerla utilizando la función sscanf ( ), le decimos a la función en el primer argumento que linea es la cadena a utilizar para su entrada, el resto de los argumentos se manejan igual que en la función scanf ( ). Observe que en este caso si utilizamos punteros porque necesitamos regresar datos de la función y observe además que utilizamos varias formas para declarar punteros, las primeras dos simplemente declaran la dirección de los elementos del array, mientras que los últimos tres aprovechan el hecho que resultado, sin el subíndice, es un puntero. Finalmente y para agregarle más interés, los datos se despliegan en orden inverso. |