\chapter{Entrada de datos por teclado y salida por consola }

Una parte importante de la solución de cualquier problema es la presentación de resultados. Es este capítulo analizaremos a fondo las características de formato printf, scanf, getche y gets en C.

\section {Entrada Salida en C}.


Las funciones de entrada salida se encuentran en la librería \verb"#include stdio.h" y son un conjunto de funciones que nos permiten realizar entrada de datos por teclado, salida a pantalla y entrada y salida a archivos. En este capítulo solamente se analizaran algunas de las funciones de entrada desde teclado y salida a pantalla. Las funciones que tienen que ver con archivos se dejarán para capiítulos posteriores.

Algunas de las funciones de entrada salida son: printf, puts, scanf, gets, getchar, etc.

\subsection {Función prinft}

La función printf se utiliza para escribir una cadena de caracteres o bien un conjunto de números con formato. La sintaxis general de esta función es

\begin{verbatim}
printf("Cadena de formato de control", argumentos);
\end{verbatim}

Los formatos numéricos de esta función se muestran a continuación.

\begin{tabular}{|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
  Especificador & Descripción \\
  \hline
  d & Despliega un entero decimal con signo \\
  \hline
  i & Despliega un entero decimal con signo \\
  \hline
  o & Muestra un entero octal sin signo \\
  \hline
  u & Muestra un estero decimal sin signo \\
  \hline
  x o X & Muestra un entero en Hexadecimal \\
        & x las letras aparecen con minúsculas \\
        & X las letras aparecen con mayúsculas \\
  \hline
  h o l & Se coloca antes de cualquier especificador \\
        & de conversión de enteros para indicar short o\\
        & bien long, respectivamente \\
  \hline
\end{tabular}

Un ejemplo del uso de esta función para el caso de enteros se muestra en la siguiente código

\begin{verbatim}
Ejemplo formatos_enteros.c

/**
  * Ejemplo para mostrar los diferentes formatos de
  * la función printf, con numeros enteros.
*/

#include <stdio.h>

int main() {
    printf("%d\n", 511);
    printf("%i\n", 511);
    printf("%d\n", +511);
    printf("%d\n", -511);
    printf("%hd\n", 32000);
    printf("%ld\n", 2000000000);
    printf("%o\n", 511);
    printf("%u\n", 511);
    printf("%u\n", -511);
    printf("%x\n", 511);
    printf("%X\n", 511);

    return 0;
}

\end{verbatim}

Para imprimir números flotantes, la función printf, utiliza los siguientes especificadores

\begin{tabular}{|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
  Especificador & Descripción \\
  \hline
  e o E & Muestra un valor en punto flotante en notación exponencial \\
  \hline
  f & Muestra valores de punto flotante \\
  \hline
  g o G & Despliega un valor en punto flotante, ya sea en la
  forma\\
    & forma de punto flotante f o en la forma \\
    & exponencial e o E \\
  \hline
  L & Indicador de flotante largo long double\\
  \hline
\end{tabular}

\begin{verbatim}
// Ejemplo formatos_flotantes.c

/**
  * Ejemplo para mostrar los diferentes formatos de
  * la función printf, con numeros flotantes.
*/

#include <stdio.h>

int main() {
    printf("%e\n", 1234567.89);
    printf("%e\n", +1234567.89);
    printf("%E\n", -1234567.89);
    printf("%f\n", 1234567.89);
    printf("%g\n", 1234567.89);
    printf("%G\n", 1234567.89);

    return 0;
}
\end{verbatim}

Para imprimir caracteres y mensajes (cadenas de caracteres), el formato de la función printf es:

\begin{tabular}{|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
  Especificador & Descripción \\
  \hline
  c & imprime un caracter \\
  s & imprime una cadena de caracteres \\
  \hline
\end{tabular}

\begin{verbatim}
// Ejemplo formatos_cadenas.c

/**
*  Este programa muestra los diferentes formatos para i
*  imprimir caracteres y cadenas de caracteres
*/

#include <stdio.h>

int main() {
    char a = 'A';
    char cadena[] = "Esto es una cadena de texto";
    char *cadenap = "Esto tambien es una cadena de texto";

    printf("%c\n", a);
    printf("%s\n", "Esto es una cadena de texto");
    printf("%s\n", cadena);
    printf("%s\n", cadenap);

    return 0;
}
\end{verbatim}

\subsection{funcion puts}

Esta función se utiliza para imprimir una cadena de texto. El formato de la función es puts(char *), lo cual significa que recibe un apuntador a una cadena de texto  y el ejemplo del programa Hola Mundo queda como:

\begin{verbatim}
#include <stdio.h>

int main ()
{
  char string [] = "Hello world!";
  puts (string);
}
\end{verbatim}

\section{Entrada por teclado}

\subsection {función scanf}

Esta función se puede utilizar para la introducción de cualquier combinación de valores numéricos o caracteres. En términos generales la función scanf se escribe:

\begin{verbatim}
scanf(cadena de control, arg1,arg2,...,argn);
\end{verbatim}

Donde cadena de control hace referencia a una cadena de caracteres que contiene cierta información sobre el formato de los datos y arg1,arg2,...,argn son argumentos que representan los datos. (En realidad los argumentos representan punteros que indican las direcciones de memoria en donde se encuentran los datos. Esto se verá más adelante).

En la cadena de control se incluyen grupos de caracteres, uno por cada dato de entrada. Cada grupo debe comenzar con el signo de porcentaje, que irá seguido, en su forma más sencilla, de un carácter de conversión que indica el tipo de dato correspondiente.

\begin{tabular}{|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
  Carácter & Significado \\
  de conversión & \\
  \hline
  c & El dato es un carácter. \\
  d & El dato es un entero decimal. \\
  e & El dato es un valor en coma flotante. \\
  f & El dato es un valor en coma flotante. \\
  g & El dato es un valor en coma flotante. \\
  h & El dato es un entero corto. \\
  i & El dato es un entero decimal, octal o hexadecimal. \\
  o & El dato es un entero octal.\\
  s & El dato es una cadena de caracteres. \\
  u & El dato es un entero decimal sin signo. \\
  x & El dato es un entero hexadecimal. \\
  \texttt{[...]} &  El dato es una cadena de caracteres \\
    & que puede incluir caracteres de espaciado.\\
  \hline
\end{tabular}

Dado que la función scanf requiere de un apuntador a la variable, cada nombre de variable debe ir precedido por un ampersand \(\&\). Los datos que se introducen deben corresponderse en tipo y orden con los argumentos de la función scanf. En el caso de que la variable sea un apuntador y/o un arreglo no será necesario colocarlo tal como se muestra en el siguiente ejemplo.

Ejemplo de utilización de scanf:

\begin{verbatim}
// Ejemplo entrada_scanf.c

/**
* Ejemplo para mostrar el uso de la funcion scanf
*/

#include <stdio.h>

int main () {
  char str [80];
  int i;

  printf ("Ingrese su nombre : ");
  scanf ("%s",str);
  printf ("Ingrese su edad: ");
  scanf ("%d",&i);
  printf ("Sr. %s , %d aÒos de edad.\n",str,i);
  printf ("Ingrese un numero hexadecimal : ");
  scanf ("%x",&i);
  printf ("Usted dio el numero %#x (%d).\n",i,i);

  return 0;
}
\end{verbatim}

\subsection {función getch}

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).

Ejemplo:

\begin{verbatim}
// Ejemplo entrada_caracter.cpp

/**
* Pide un caracter desde el teclado.
*/

#include <stdio.h> #include <conio.h>

int main()

{

  char letra;

  printf( "Introduce una letra: " );


  letra = getche();

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

  return 0;

}
\end{verbatim}

\subsection {Instrución gets}

Esta función es la alternativa para captura de strings que tengan espacios en blanco intermedios cosa que scanf \%s no puede hacer. Su formato completo es :

\begin{verbatim}
gets(variable string);
\end{verbatim}

\begin{verbatim}
// Ejemplo gets_puts.c

/**
*  Ejemplo que muestra el uso de gets y puts
*/

#include <stdio.h>    // Para gets() y puts() #include <conio.h>
// Para clrscr() y gotoxy()


void main() {
  char nombre[31];   // Declara un arreglo de 31 caracteres
  char saludo1[] = "HOLA,"; //Constante de caracteres


  puts("Cual es tu nombre ? "); //Despliega cadena de car.
  gets(nombre);   // Lee cadena de caracteres
  puts(saludo1);
  puts(nombre);

}
\end{verbatim}

Un ejemplo donde se muestra la entrada y salida utilizando todos los tipos es el que se muestra a continuación.

\begin{verbatim}
/* 
 * File:   lectura_tipos.c
 * Author: felix
 *
 * Created on 11 de septiembre de 2011, 20:18
 */

#include <stdio.h>
#include <stdlib.h>

int main() {
    
    // Para leer un entero
    
    int d;
    printf("Leyendo un entero d = ");
    scanf("%d", &d);
    printf("El entero leido es %d \n", d);
    
    // Para leer un caracter

    char c;
    printf("Leyendo un caracter c = ");
    scanf("%s", &c);
    printf("El caracter leido es %c\n", c);
    
    // Para leer un flotante
    
    float f;
    printf("Leyendo un Florante f = ");
    scanf("%f", &f);
    printf("El flotante leido es %f\n", f);
    
    
    // Para leer una cadena de caracteres
    
    char s[20];
    printf("Leyendo una cadena de caracteres s = ");
    scanf("%s", s);
    printf("La cadena es %s\n",s);
    
    return (0);
}

\end{verbatim}

\section {Ejemplos}

Utilizando la entrada salida por consola, reescribir los programas de la sección \ref{sec:ejemplos_areas}, para que permitan utilizar valores dados desde teclado.

\subsection{Cálculo de Áreas}

\subsubsection{En C}

\begin{verbatim}
// Ejemplo Areas_volumenes.c

/**
 * <p>Title: Calculo de Areas de figuras</p>
 * <p>Description: Calcula el area y volumen de simples figuras utilizando 
 * lectura de datos desde el teclado</p>
 * <p>Copyright: Copyright (c) 2005</p>
 * <p>Company: UMSNH</p>
 * @author Dr. Felix Calderon Solorio
 * @version 1.0
 */

#include <stdio.h>

int main()
{
  // datos
  float base, altura, radio;
  
  printf("Dame el valor de la base ");
  scanf("%f", &base);
    
  printf("Dame el valor de altura ");
  scanf("%f", &altura);

  printf("%f\n", altura);
    
  printf("Dame el radio ");
  scanf("%f", &radio );

  // areas

  float Atriangulo  = (base * altura) / 2.0;
  float Acuadrado   = base*base;
  float Arectangulo = base * altura;

  // volumenes

  float Abase       = 3.1416*radio*radio;
  float Vcilindro   = Abase * altura ;
  float Vcono       = Abase * altura / 3.0;

  printf("Area de triangulo  = %f\n", Atriangulo);
  printf("Area de cuadrado   = %f\n", Acuadrado);
  printf("Area de rectangulo = %f\n", Arectangulo);
  printf("Volumen cilindro   = %f\n", Vcilindro);
  printf("Volumen cono       = %f\n", Vcono);

  return 0;
}
\end{verbatim}

\subsection{Ley de Ohm y Análisis de transistores}

Resolver el problema de la sección \ref{sec:ejemplos_areas} utilizando instrucciones de entrada salida.

\subsubsection{En C}
\begin{verbatim}
// Ejemplo ec037.cpp

/**
 * Title: Calculo de la ganancia de voltaje para un transistor
 * Description: Programa para determinar ganancias de voltaje utilizando dato
 * desde el teclado
 * Copyright: Copyright (c) 2005
 * Company: UMSNH
 * author Dr. Felix Calderon Solorio
 * version 1.0
 */

#include <stdio.h>

int main() {

  float Vi, Re, Rc, R;
  float I, Il, Vl, Av;

  printf("Dame el voltaje de entrada Vi = ");
  scanf("%f", &Vi);
  printf("Dame el valor de la Resistencia de emisor Re = ");
  scanf("%f", &Re);
  printf("Dame el valor de la Resistencia de colector Rc = ");
  scanf("%f", &Rc);
  printf("Dame el valore de la Resistencia de carga Rl = ");
  scanf("%f", &R);

  // calculo de la corriente de emisor.

  I = Vi/Re;
  printf("I = %f\n", I);

  // Asumiendo una ganacia alpha = 1 y que Ic = Ie

  Il = I;
  printf("Il = %f\n", Il);

  // el voltaje en la resistencia R es

  Vl = Il*R;
  printf("Vl = %f\n", Vl);


  // finalmente la ganacia de voltaje es
   Av = Vl/Vi;
  printf("Av = %f\n", Av);

  return 0;
}

\end{verbatim}

\subsection{Ejemplo Mayor de edad}

El siguiente código permite determinar si una persona es mayor de edad en el año 2011 dependiendo del año en que nació.

\begin{verbatim}
/* 
 * File:   mayor_edad.c
 * Author: felix
 *
 * Created on 11 de septiembre de 2011, 20:36
 */

#include <stdio.h>
#include <stdlib.h>

int main() {
    int edad, anio;
    printf("Dame el anio en que naciste ");
    scanf("%d", &anio);
    edad = 2011-anio;
    char mayor = 'S'*(edad>=18) + 'N'*(edad<18);
    printf("\n%c\n", mayor);
    
    return (0);
}

\end{verbatim}




