Análisis y Diseño de Algoritmos                                                                                                      

Prof: Ing. Victor Garro

Asistente: Marco Elizondo Vargas

 

PROGRAMACION EN C++

 

 

CAPITULO 3 Entradas y SALIDAS

 

 

Entrada y Salida en C

La biblioteca STDIO.H

Es la librería estándar del lenguaje de programación C el archivo de cabecera que contiene las definiciones de macros, las constantes, las declaraciones de funciones y la definición de tipos usados por varias operaciones estándar de entrada y salida. Por motivos de compatibilidad, el lenguaje de programación C++ (derivado de C) también tiene su propia implementación de estas funciones, que son declaradas con el archivo de cabecera cstdio.

Las funciones declaradas en stdio.h son sumamente populares.

Operaciones de salida.

Printf: Imprimir en pantalla

Para utilizar la función printf en nuestros programas debemos incluir la directiva:

#include <stdio.h>

Si sólo queremos imprimir una cadena basta con escribir la siguiente línea de código.

printf( "Cadena" );

Como resultado muestra en pantalla:

Cadena

Lo que pongamos entre las comillas es lo que vamos a sacar por pantalla.

Si volvemos a usar otro printf, por ejemplo:

#include <stdio.h>

void main()

{

printf( "Cadena" );

printf( "Segunda" );

}

Obtendremos:

CadenaSegunda

Este ejemplo nos muestra cómo funciona printf. Para escribir en la pantalla se usa un cursor que no vemos. Cuando escribimos algo el cursor va al final del texto. Cuando el texto llega al final de la fila, lo siguiente que pongamos irá a la fila siguiente. Si lo que queremos es sacar cada una en una línea deberemos usar "\n". Es el indicador de retorno de carro. Lo que hace es saltar el cursor de escritura a la línea siguiente:

#include <stdio.h>

void main()

{

printf( "Cadena\n" );

printf( "Segunda" );

}

y tendremos:

Cadena

Segunda

También podemos poner más de una cadena dentro del printf:

printf( "Primera cadena" "Segunda cadena" );

Lo que no podemos hacer es meter cosas entre las cadenas:

printf( "Primera cadena" texto en medio "Segunda cadena" );

esto no es válido. Cuando el compilador intenta interpretar esta sentencia se encuentra "Primera cadena" y luego texto en medio, no sabe qué hacer con ello y da un error.

Pero ¿qué pasa si queremos imprimir el símbolo " en pantalla? Por ejemplo imaginemos que queremos escribir:

Esto es "extraño"

Si para ello hacemos:

printf( "Esto es "extraño"" );

obtendremos unos cuantos errores. El problema es que el símbolo " se usa para indicar al compilador el comienzo o el final de una cadena. Así que en realidad le estaríamos dando la cadena "Esto es", luego extraño y luego otra cadena vacía "". Pues resulta que printf no admite esto y de nuevo tenemos errores.

La solución es usar \". Veamos:

printf( "Esto es \"extraño\"" );

Esta vez todo irá como la seda. Como vemos la contrabarra '\' sirve para indicarle al compilador que escriba caracteres que de otra forma no podríamos.

Esta contrabarra se usa en C para indicar al compilador que queremos meter símbolos especiales. Pero ¿Y si lo que queremos es usar '\' como un carácter normal y poner por ejemplo Hola\Adiós? Pues muy fácil, volvemos a usar '\':

printf( "Hola\\Adiós" );

y esta doble '\' indica a C que lo que queremos es mostrar una '\'.

Operaciones de entrada

Algo muy usual en un programa es esperar que el usuario introduzca datos por el teclado. Para ello contamos con varias posibilidades: Usar las funciones de la biblioteca estándar, crear nuestras propias interrupciones de teclado (MS-Dos) o usar funciones de alguna biblioteca diferente (como por ejemplo Allegro).

En este trabajo topare solo la primera opción, usando las funciones de la biblioteca estándar. Pero veamos por encima las otras posibilidades.

Las funciones estándar están bien para un programa sencillito. Pero cuando queremos hacer juegos por ejemplo, no suelen ser suficiente. Demasiado lentas o no nos dan todas las posibilidades que buscamos, como comprobar si hay varias teclas pulsadas. Para solucionar esto tenemos dos posibilidades:

La más complicada es crear nuestras propias interrupciones de teclado. ¿Qué es una interrupción de teclado? Es un pequeño programa en memoria que se ejecuta continuamente y comprueba el estado del teclado. Podemos crear uno nuestro y hacer que el ordenador use el que hemos creado en vez del suyo.

Otra posibilidad más sencilla es usar una biblioteca que tenga funciones para controlar el teclado. Por ejemplo si usamos la biblioteca Allegro, ella misma hace todo el trabajo y nosotros no tenemos más que recoger sus frutos con un par de sencillas instrucciones. Esto soluciona mucho el trabajo y nos libra de tener que aprender cómo funcionan los aspectos más oscuros del control del teclado.

Vamos ahora con las funciones de la biblioteca estándar antes mencionada.

Scanf

El uso de scanf es muy similar al de printf con una diferencia, nos da la posibilidad de que el usuario introduzca datos en vez de mostrarlos. No nos permite mostrar texto en la pantalla, por eso si queremos mostrar un mensaje usamos un printf delante. Un ejemplo:

#include <stdio.h>

void main()

{

int num;

printf( "Introduce un número " );

scanf( "%i", &num );

printf( "Has tecleado el número %i\n", num );

}

Primero vamos a ver unas nota de estética, para hacer los programas un poco más elegantes. Parece una tontería, pero los pequeños detalles hacen que un programa gane mucho. El scanf no mueve el cursor de su posición actual, así que en nuestro ejemplo queda:

Introduce un número _ /* La barra horizontal indica dónde esta el cursor */

Esto es porque en el printf no hemos puesto al final el símbolo de salto de línea '\n'. Además hemos dejado un espacio al final de Introduce un número: para que así cuando tecleemos el número no salga pegado al mensaje. Si no hubiésemos dejado el espacio quedaría así al introducir el número 120 (es un ejemplo):

Introduce un número120

Veamos cómo funciona el scanf. Lo primero nos fijamos que hay una cadena entre comillas. Esta es similar a la de printf, nos sirve para indicarle al compilador qué tipo de datos estamos pidiendo. Como en este caso es un integer usamos %i. Después de la coma tenemos la variable donde almacenamos el dato, en este caso 'num'.

Fíjate que en el scanf la variable 'num' lleva delante el símbolo &, este es muy importante, sirve para indicar al compilador cual es la dirección (o posición en la memoria) de la variable.

Podemos preguntar por más de una variable a la vez en un sólo scanf, hay que poner un %i por cada variable:

#include <stdio.h>

void main()

{

int a, b, c;

printf( "Introduce tres números: " );

scanf( "%i %i %i", &a, &b, &c );

printf( "Has tecleado los números %i %i %i\n", a, b, c );

}

De esta forma cuando el usuario ejecuta el programa debe introducir los tres datos separados por un espacio.

También podemos pedir en un mismo scanf variables de distinto tipo:

#include <stdio.h>

void main()

{

int a;

float b;

printf( "Introduce dos números: " );

scanf( "%i %f", &a, &b );

printf( "Has tecleado los números %i %f\n", a, b );

}

A cada modificador (%i, %f) le debe corresponder una variable de su mismo tipo. Es decir, al poner un %i el compilador espera que su variable correspondiente sea de tipo int. Si ponemos %f espera una variable tipo float.

Getch y getche

Si lo que queremos es que el usuario introduzca un carácter por el teclado usamos las funciones getch y getche. Estas esperan a que el usuario introduzca un carácter por el teclado. La diferencia entre getche y getch es que la primera saca por pantalla la tecla que hemos pulsado y la segunda no (la e del final se refiere a echo=eco). Ejemplos:

#include <stdio.h>

void main()

{

char letra;

printf( "Introduce una letra: " );

fflush( stdout );

letra = getche();

printf( "\nHas introducido la letra: %c", letra );

}

Resultado:

Introduce una letra: a

Has introducido la letra: a

¿Qué es el fflush( stdout )?. Pues bien, cuando usamos la función printf, no escribimos directamente en la pantalla, sino en una memoria intermedia (lo que llaman un bufer). Cuando este bufer se llena o cuando metemos un carácter '\n' es cuando se envía el texto a la pantalla. En este ejemplo yo quería que apareciera el mensaje Introduce una letra: y el cursor se quedara justo después, es decir, sin usar '\n'. Si se hace esto, en algunos compiladores el mensaje no se muestra en pantalla hasta que se pulsa una tecla (probar). Y la función fflush( stdout ) lo que hace es enviar a la pantalla lo que hay en ese bufer.

Y ahora un ejemplo con getch:

#include <stdio.h>

void main()

{

char letra;

printf( "Introduce una letra: " );

fflush( stdout );

letra = getch();

printf("\n has introducido la letra :%c", letra );

}

Resultado:

Introduce una letra:

Has introducido la letra: a

Como vemos la única diferencia es que en el primer ejemplo se muestra en pantalla lo que escribimos y en el segundo no.

ANEXOS

Usos de printf y scanf

printf("Mensaje");
printf("Mensaje %d",Variable);
printf("Mensaje %d",Variable:2:3);
cprintf("Mensaje");

Escribe Mensaje en la pantalla
Escribe Mensaje y el valor de la Variable en pantalla
Escribe Mensaje y el valor de la Variable con 2 enteros y 3 decimales
Escribe Mensaje en
color especificado

scanf("%d",&Variable);
scanf("%d %f",&Variable1,&Variable2);

Asigna valor entero a Variable
Asigna valor entero a Variable1 y valor real a Variable2

 

 

 

Nota

C++ ofrece una alternativa a las llamadas de funcion printf y scanf para manejar la entrada/salida de los tipos y cadenas de datos estandar. Así en lugar de printf usamos el flujo estandar de salida cout y el operador << ("colocar en"); y en lugar de scanf usamos el flujo de entrada estandar cin y el operador >>("obtener de"). Estos operadores de inserción y extracción de flujo, a diferencia de printf y scanf, no requieren de cadenas de formato y de formato y de especificadotes de conversión para indicar los tipos de datos que son extraidos o introducidos.

Las siguientes funciones nos resultan indispensable para poder brindar una mejor presentación de los datos en pantalla.

Gotoxy: Posicionando el cursor (DOS)

Esta función sólo está disponible en compiladores de C que dispongan de la biblioteca <conio.h>

Hemos visto que cuando usamos printf se escribe en la posición actual del cursor y se mueve el cursor al final de la cadena que hemos escrito.

Vale, pero ¿qué pasa cuando queremos escribir en una posición determinada de la pantalla? La solución está en la función gotoxy. Supongamos que queremos escribir 'Hola' en la fila 10, columna 20 de la pantalla:

#include <stdio.h>

#include <conio.h>

void main()

{

gotoxy( 20, 10 );

printf( "Hola" );

}

(Nota: para usar gotoxy hay que incluir la biblioteca conio.h).

Fíjate que primero se pone la columna (x) y luego la fila (y). La esquina superior izquierda es la posición (1, 1).

Clrscr: Borrar la pantalla (DOS)

Ahora ya sólo nos falta saber cómo se borra la pantalla. Pues es tan fácil como usar:

clrscr()

(clear screen, borrar pantalla).

Esta función solo borra la pantalla, sino que además sitúa el cursor en la posición (1, 1), en la esquina superior izquierda.

#include <stdio.h>

#include <conio.h>

void main()

{

clrscr();

printf( "Hola" );

}

Este método sólo vale para compiladores que incluyan el fichero stdio.h.

 

Entrada y Salida en C++

 3.1 La biblioteca iostream

C++ proporciona una nueva biblioteca de funciones que realizan operaciones de E/S: la biblioteca iostream. Esta biblioteca es una implementación orientada a objetos y está basada, al igual que stdio, en el concepto de flujos. Cuando se introducen caracteres desde el teclado, puede pensarse en caracteres que fluyen desde el teclado a las estructuras de datos del programa. Cuando se escribe en un archivo, se piensa en un flujo de bytes que van del programa al disco.
Para acceder a la biblioteca iostream se debe incluir el archivo iostream.h. Este archivo contiene información de diferentes funciones de E/S. Define también los objetos cin y cout.

3.2 Manipuladores de salida

La biblioteca iostream define varios operadores particulares, llamados manipuladores, que le permiten controlar precisamente, el formato de los datos visualizados. Situando un manipulador en la cadena de operadores <<, se puede modificar el estado del flujo.

Cuando comienza la ejecución de un programa escrito en C++ se abren de forma automática cuatro flujos predefinidos:

Para realizar operaciones de entrada y salida C++ permite utilizar los siguientes operadores, que se encuentran sobrecargados

·                    cout << ``Cadena a imprimir por pantalla'' << nombre_variable
·                         << ``\n'';

De esta forma se mostrará por pantalla el mensaje que se encuentra entre comillas, en la misma línea el valor que tenga en ese momento nombre_variable y a continuación un retorno de carro.

·                   cin >> variable_entrada;

De esta forma en la variable de nombre variable_entrada se almacenará el valor introducido desde teclado. Hay que notar que si se ha tecleado una cadena de caracteres en variable_entrada sólo se guardarán aquellos desde el comienzo hasta el primer espacio en blanco.


Una característica importante de un flujo que debe tratar con valores numéricos es la base de los números. Hay tres manipuladores (dec, hex y oct) para controlar la situación. La base por omisión es 10 y por tanto sólo será necesario indicar dec cuando se haya fijado la base a otro valor:

cout <<oct<<x<<endl;
cout <<dec<<x<<endl;

Los manipuladores que toman argumentos se declaran en iomanip.h, el resto en iostream.h.

Manipuladores

Aplicación

Descripción

dec

cout<<dec<<x;

Conversión a decimal

 

cin>>dec>>x;

 

hex

out<<hex<<x;

conversión a hexadecimal

 

cin>>hex>>x;

 

oct

cout<<oct<<x;

Conversión a octal

 

cin>>oct>>x;

 

ws

cin>>ws;

Salta espacios en la entrada

endl

cout<<endl;

Envía carácter fin de línea

flush

cout<<flush;

Limpia el buffer

setfill(int)

cout<<setfill('*';

Fija el carácter de rellenado

setprecision(int)

cout<<setprecision(6);

Fija la conversión en coma flotante al nº de dígitos especificado

setw(int)

cout<<setw(6)<<x;

Fija la anchura

 

cin>>setw(10)>>x;

 

Con setw() los valores numéricos se justifican a derechas y los datos carácter a izquierdas.

La información de la justificación de la salida se almacena en un modelo o patrón de bits de una clase llamada ios, que constituye la base de todas las clases de flujos. Puede establecer o reinicializar bits específicos utilizando los manipuladores setiosflags() y resetiosflags() respectivamente.

Para utilizar cualquiera de los indicadores de formato hay que insertar el manipulador setiosflags() con el nombre del indicador como argumento. Hay que utilizar resetiosflags() con el mismo argumento para invertir el estado del formato antes de utilizar el manipulador setiosflags().

Indicador

Significado del indicador activado

ios::left

Justifica la salida a la izquierda

ios::right

Justifica la salida a la derecha

ios::scientific

Utiliza notación científica para números de coma flotante

ios::fixed

Utiliza notación decimal para números de coma flotante

ios::dec

Utiliza notación decimal para enteros

ios::hex

Utiliza notación hexadecimal para enteros

ios::oct

Utiliza notación octal para enteros

ios::showpos

Muestra un signo positivo cuando se visualizan valores positivos

IMPORTANTE: C++ permite que se sigan utilizando printf() y scanf(), sin embargo es más conveniente la utilización de los operadores definidos porque éstos permiten operar, además de con todos los tipos de datos que admite C, con objetos.