You are on page 1of 39

De acuerdo a su definicin, C++ es una extensin del lenguaje C, un

supercunjunto, esto implica para quin decide iniciar sus estudios en C++ que para
empezar dispone de un lenguaje completo como soporte a los nuevos conceptos
introducidos por C++, esto significa que todo lo que podemos programar en ANSI-C
funciona en C++ y esto a su vez es una buena razn para afirmar la importancia
que tiene en el aprendizaje de C++ el conocimiento previo del lenguaje C, por lo
tanto se supone que el lector est familiarizado con todo lo expuesto en el curso en
lnea de la seccin programando en C.

Comentarios en C++
Es natural tratar en primer lugar la manera de hacer comentarios en el cdigo
fuente de un programa escrito en C++, y para probar la afirmacin hecha en el
prrafo anterior, el siguiente cdigo escrito en C debe compilar perfectamente. Le
llamaremos al cdigo comenta1.cpp, habr notado que la extensin *.cpp se
refiere a C-plus-plus. Un compilador de C++ sabe que el cdigo est escrito en
C++ precisamente por la extensin del archivo que contiene el cdigo fuente.

/******************************************/
/* comenta1.cpp */
/******************************************/

#include <stdio.h>

int main()
{
float corriente, voltaje, resistencia; /* tres variables */

printf("Este programa calcula volaje de acuerdo a la ley de
Ohm\n");
printf("Valor de la corriente, en amperes?\n");
scanf("%f", &corriente);
printf("Valor de la resistencia, en ohms?\n");
scanf("%f", &resistencia);

voltaje=corriente*resistencia; /* calculo de voltaje */

printf("El valor del voltaje es de %f voltios\n", voltaje);

return 0;
}
Aunque se trata de un programa escrito en C, por la sencilla razn de que el
archivo de cdigo fuente lleva la extensin *.cpp, el compilador lo trata como un
cdigo C++ vlido, esto demuestra la total compatibilidad de que disponemos al
programar en C++ con respecto al lenguaje C. Empero C++ introduce una manera
ms prctica de hacer comentarios al utilizar doblemente el smbolo de barra
inclinada para indicarle al compilador que el resto de la lnea de cdigo que sigue a
la doble barra inclinada es un comentario y por lo tanto debe ignorarse en el
proceso de compilacin. Al contrario del mecanismo para hacer comentarios en C
que puede abarcar varias lneas de cdigo, el estilo utilizado en C++ slo es vlido
hasta el final del rengln en donde es utilizada la doble barra inclinada. Ahora
nuestro programa lo modificamos para utilizar comentarios en C++:

//******************************************
// comenta2.cpp
//******************************************

#include <stdio.h>

int main()
{
float corriente, voltaje, resistencia; // tres variables

printf("Este programa calcula volaje de acuerdo a la ley de
Ohm\n");
printf("Valor de la corriente, en amperes?\n");
scanf("%f", &corriente);
printf("Valor de la resistencia, en ohms?\n");
scanf("%f", &resistencia);

voltaje=corriente*resistencia; // calculo de voltaje


printf("El valor del voltaje es de %f voltios\n", voltaje);

return 0;
}
Se aprecia de inmediato la comodidad del nuevo estilo de introducir comentarios
en el cdigo fuente de C++ adems del doble beneficio que representa el poder
seguir utilizando los comentarios en C. Se debe tener ciertas precauciones al
manejar los comentarios pues aunque C++ reconoce ambos mtodos, el estndar
ANSI-C en s no reconoce la mecnica de C++ para los comentarios, dicho en otras
palabras, no escriba cdigo en ANSI-C pensando en trminos de C++, lo contrario,
como ya lo probamos, es perfectamente vlido.
Volver al principio

La librera iostream.h
Aunque comenta2.cpp es un programa C++ vlido sabemos que es en realidad
un programa escrito en C y nosotros estamos interesados en aprender los aspectos
nuevos introducidos en C++, pues bien, un cambio muy importante es en la
manera en que se maneja la entrada y salida de datos en el programa. Al igual que
en C, C++ no incluye operaciones de entrada y salida como parte del lenguaje en
s, en cambio define la librera iostream que agrega funciones de entrada y salida
muy elegantes. Al programar en C nos familiarizamos con el archivo stdio.h en
donde est definida entre otras, la funcin printf() que como sabemos sirve para
escribir datos en el dispositivo estndar de salida, que en la gran mayora de los
casos es el monitor de la computadora. Como la funcin printf() se desarroll casi
desde los origenes de C, la funcin ha sufrido una serie de transformaciones que la
ha hecho crecer en tamao, como resultado de esto, cuando incluimos la funcin
printf() en nuestro programa C tambien incluimos todas las opciones agregadas con
el tiempo aunque no las utilicemos. Un caso similar sucede con la funcin scanf().
C++ propone una solucin muy interesante al tratar las operaciones de
entrada-salida (E/S) no como una funcin, sino como una clase que implementa
una gran capacidad de formatos para entrada y salida de datos, de sta manera el
programador C++ toma slo las carctersticas que el trabajo requiere. Aunque no
hemos definido qu es una clase, tenga en cuenta que en C++ las operaciones de
E/S estn definidas en una clase, ste es un punto importante. Existen cuatro flujos
de E/S (iostreams) predefinidos:
cin, asociado al dispositivo de entrada estndar.
cout, asociado al dispositivo de salida estndar.
cerr, asociado al dispositivo de error estndar.
clog, salida almacenada temporalmente para el dispositivo de error
estndar.
Tomando en cuenta lo dicho estamos en condicin de modificar el programa
anterior para utilizar los flujos de E/S, de sta manera ya no necesitamos el archivo
de cabecera stdio.h el cual lo hemos sustituido por el archivo iostream.h que nos
permite utilizar los flujos de E/S

//******************************************
// entsal.cpp
//******************************************

#include <iostream.h>

int main()
{
float corriente, voltaje, resistencia; // tres variables

cout << "Este programa calcula volaje de acuerdo a la ley de
Ohm\n";
cout << "Valor de la corriente, en amperes?\n";
cin >> corriente;
cout << "Valor de la resistencia, en ohms?\n";
cin >> resistencia;

voltaje=corriente*resistencia; // calculo de voltaje

cout << "El valor del voltaje es de " << voltaje << " voltios\n";

return 0;
}
El programa entsal.cpp es idntico a comenta2.cpp, sin embargo es importante
hacer notar lo siguiente, no se recomienda mezclar la funcin printf() con el flujo de
salida cout en el mismo programa ya que se generaran dos flujos independientes
hacia el mismo dispositivo de salida con resultados impredecibles. Comparando los
dos ltimos programas es fcil asimilar el uso de cin y cout. Utilizamos el flujo de
salida cout en conjuncin con el operador de insercin, << para mostrar un
mensaje en la pantalla del monitor. De manera similar, utilizamos el flujo de
entrada cin en conjuncin con el operador de extraccin, >> para asignar un valor
a las variables llamadas corriente y resistencia. Observe que no es necesario utilizar
el operador de direccin & con las variables de entrada. La lnea 19 demuestra el
uso de varios operadores de insercin en una sola lnea de cdigo, observe que las
cadenas y los datos se despliegan en el orden en que se escriben en la lnea de
cdigo, tambien observe el espacio en blanco al final de la primera cadena y al
principio de la segunda cadena de sta lnea de cdigo.
En trminos generales declaramos el archivo de cabecera iostream.h para
operaciones de flujos de E/S, ste suele incluir otros archivos de cabecera
adicionales que declaran funciones, macros, clases y valores necesarios en las
operaciones con flujos de entrada (istream.h), flujos de salida (ostream.h), buffers
de flujos (streamb.h) y manipuladores de flujo (imanip.h) principalmente.
Analizaremos stas tres partes por separado.
Volver al principio

Utilizando manipuladores
Un manipulador es un valor que podemos extraer insertar de un flujo de E/S
para lograr un efecto especial en estos. Un manipulador parece un objeto que
insertamos extraemos de un flujo pero generalmente solo cambia el estado del
mismo. Existen tres manipuladores comunes, dec, oct y hex los cuales permiten
desplegar un valor numrico en base decimal, octal y hexadecimal
respectivamente, y otros ms declarados en el archivo iomanip.h entre los que
figuran setw(), setfill(), setprecision(), setiosflags() y resetiosflags().
Manipuladores bsicos
En el siguiente programa, manipu01.cpp, se demuestra el uso de los
manipuladores bsicos oct, hex, y dec. El programa inicia solicitndole introducir un
nmero, mismo que se almacena en la variable de tipo int llamada numero, en
forma predeterminada, el sistema despliega los valores numricos utilizando la
base 10, esto se demuestra en el primer mensaje desplegado por el programa en la
lnea 14. Enseguida se utiliza el operador de insercin (<<) para introducir el
manipulador oct que cambia la base para despliegue numrico a octal por lo que el
valor contenido en la variable llamada numero se despliega en pantalla en su
equivalente de base 8. Observe que el contenido de la variable no ha cambiado,
solo se modifica la forma para desplegar un valor numrico en el dispositivo
estndar de salida.

//*********************************************************
// manipu01.cpp
//*********************************************************

#include <iostream.h>

int main()
{
int numero;

cout <<"Introduzca un numero" << endl;
cin >> numero;

cout <<"El numero introducido en base decimal es: "
<< numero << endl;

cout << oct; // Ahora trabajamos en base octal
cout << "Cambiando a base octal el numero introducido se "
"despliega asi: " << numero << endl;

cout << hex; // Trabajamos en base hexadecimal
cout << "El mismo numero en base hexadecimal es: ";
cout << numero << endl;
cout << "Introduzca otro numero" << endl;
cin >> numero;
cout << "El numero es: " << numero << endl;

cout << dec; // Restituimos la base predeterminada

return 0;
}
De manera similar se utiliza el operador de insercin para introducir ahora el
modificador hex que sirve para cambiar el despliegue numrico a base 16
hexadecimal, entonces el programa muestra el valor almacenado en numero pero
representado en base 16. Cuando utilizamos los manipuladores oct hex le
indicamos al sistema la base numrica que deseamos para representar nuestros
valores numricos, una vez cambiada la representacin numrica, sta permanece
hasta que especifiquemos una nueva base hasta que apaguemos el sistema, para
demostrar sta situacin, en la parte final del programa se le solicita introducir otro
nmero, observar que el despliegue en pantalla parece no coincidir con el nmero
introducido, ste fenmeno sucede porque estamos acostumbrados a pensar en
trminos generales, utilizando la base 10, pero con un anlisis ms cuidadoso
encontramos que no existe error alguno, sencillamente el programa despliega los
valores numricos utilizando el ltimo modificador especificado, que en ste caso es
de tipo hexadecimal. El programa termina utilizando una vez ms el operador de
insercin para especificar la base 10 como la deseada para representar los valores
numricos en el dispositivo estndar de salida.
Para ms informacin en relacin con los sistemas numricos consulte Sistemas
numricos y representacin de datos de la seccin Conceptos bsicos.
El archivo iomanip.h
El archivo de cabecera llamado iomanip.h define un conjunto de manipuladores
adicionales a los bsicos tratados en el prrafo anterior, generalmente se trata de
los siguientes:
setw(), se utiliza con flujos istream y ostream.
setfill(), se utiliza con flujos istream y ostream.
setprecision(), se utiliza con flujos istream y ostream.
setiosflags(), se utiliza con flujos istream.
resetiosflags(), se utiliza con flujos istream y ostream.
Empezamos estudiando el manipulador setw(), ya sea que se utilice con flujos
de entrada (istream) flujos de salida (ostream) establece el ancho de campo al
valor especificado dentro del parntesis del manipulador como se demuestra en el
programa manipu02.cpp.

//*********************************************************
// manipu02.cpp
//*********************************************************

#include <iostream.h> // para operaciones de E/S
#include <iomanip.h> // define diferentes manipuladores

int main()
{
int i;

cout << " El ancho de este campo es de 36" << endl;
for(i=1; i<6; i++)
{
cout << setw(i);
cout << "1" << endl;
cout << setw(i);
cout << "12" << endl;
cout << setw(i);
cout << "123" << endl;
cout << endl;
}
cout << setw(36);
cout << "El ancho de este campo es de 36" << endl;
return 0;
}
El manipulador setw(), como ya se dijo, establece el ancho de un campo de
salida pero su efecto solo se aplica a la salida del valor siguiente, la siguiente
operacin de insercin extraccin restablece el valor del ancho del campo a cero
que es el valor predeterminado, por sta razn se utiliza varias veces el
manipulador setw() a lo largo del programa manipu02.cpp, compilndolo podemos
apreciar los espacios en blanco a la izquierda del campo de salida que resultan de
especificar diferentes valores de tipo int.
En el siguiente programa de ejemplo, manipula03.cpp, especificamos diferentes
valores de ancho de campo para los datos correspondientes a las calificaciones de
un pequeo grupo ficticio de estudiantes con el objeto de darle al reporte de
calificaciones una mejor apariencia, en ste programa utilizamos el manipulador
setfill() para especificar que deseamos rellenar los espacios en blanco, definidos por
el manipulador setw(), con el carcter de punto. Se puede observar que al utilizar
el manipulador setfill() su efecto permanece para todos los flujos de E/S hasta que
se selecciona otro carcter diferente. Al final del programa especificamos utilizar el
carcter de espacio en blanco para rellenar los espacios, que es el carcter
predeterminado.

//*********************************************************
// manipu03.cpp
//*********************************************************

#include <iostream.h> // para operaciones de E/S
#include <iomanip.h> // define diferentes manipuladores

int main()
{
cout << setfill('.'); // rellenar con puntos

cout << "Reporte de calificaciones\n" << endl;
cout << "Roberto Andrade" << setw(20) << "85" << endl;
cout << "Andrea Gutierrez" << setw(19) << "89" << endl;
cout << "Lisseth Sanchez" << setw(20) << "87" << endl;
cout << "Anastasio Castro" << setw(19) << "75" << endl;
cout << "Barbara Clintonsky" << setw(17) << "78" << endl;
cout << "Martin Flores Garcia" << setw(15) << "91" << endl;

cout << setfill('\0'); // se restablece el carcter de llenado

return 0;
}
En el programa comenta1.cpp, escrito en C, se realiz un sencillo clculo
utilizando valores de tipo float, al ejecutarlo observamos que la salida mostrada en
la pantalla invariablemente desplegaba seis dgitos decimales, incluso introduciendo
valores que dieran por resultado un valor exacto. En comparacin, el mismo
programa escrito en C++, entsal.cpp, despliega automticamente los dgitos
decimales de acuerdo al clculo realizado, sin embargo, en ciertas aplicaciones
puede ser deseable especificar un nmero determinado de dgitos a desplegar por
el flujo de E/S. Para ste fin se utiliza el manipulador setprecision() en donde
podemos especificar mediante un valor de tipo int el nmero de dgitos a la derecha
del punto decimal a desplegar en pantalla, estudie el programa llamado
manipu04.cpp

//*********************************************************
// manipu04.cpp
//*********************************************************

#include <iostream.h> // para operaciones de E/S
#include <iomanip.h> // define diferentes manipuladores

int main()
{
int i;
double variable1=22, variable2=7;

for(i=0; i<15; i++)
{
cout << setprecision(i);
cout << variable1/variable2 << endl;
}
return 0;
}
Ya habr notado que los flujos de E/S tienen ciertos valores predefinidos y que
stos valores se pueden modificar utilizando manipuladores como oct y hex, sucede
que los flujos de E/S tienen un campo para especificar los valores correspondientes
y stos campos se llaman banderas (flags). El archivo de cabecera ios.h define
diferentes especificaciones de banderas. Mediante el uso del manipulador
setiosflags() nuestros programas pueden manipular muchas de stas banderas
utilizando a su vez el operador de alcance, identificado por un par de smbolos de
dos puntos (::) y que nos sirve para acceder a una variable de alcance global a
los miembros de una clase. Recuerde que en la siguiente leccin daremos la
definicin de una clase y demostraremos detalladamente el uso del operador de
alcance, por lo pronto es importante que conserve en mente los datos previos de
sta leccin pues sern aplicados prcticamente en todo programa que escriba en
C++.
En una determinada seccin del archivo de cabecera ios.h podemos encontrar
las definiciones para las diferentes banderas como un tipo de dato enum,
generalmente de la siguiente manera:

enum
{
skipws = 0x0001, // Salta espacios en blanco durante la
entrada
left = 0x0002, // justifica a la izquierda
right = 0x0004, // justifica a la derecha
internal = 0x0008, // relleno despus de signo indicador de
base
dec = 0x0010, // base decimal
oct = 0x0020, // base octal
hex = 0x0040, // base hexadecimal
showbase = 0x0080, // muestra indicador de base durante la
salida
showpoint = 0x0100, // punto decimal obligatorio en float
uppercase = 0x0200, // salida hex en maysculas
showpos = 0x0400, // signo positivo obligatorio
scientific = 0x0800, // notacin de tipo 3.145363E23
fixed = 0x1000, // dgitos decimales predeterminados
unitbuf = 0x2000, // desaloja flujos despus de insercin
stdio = 0x4000 // desaloja stdout, stderr despus de
insercin
};
Puede identificar fcilmente algunos de los manipuladores que ya hemos
estudiado y ahora veremos cmo se utilizan stas banderas mediante el
manipulador setiosflags() y cmo restituimos las condiciones originales mediante el
manipulaodr resetiosflags(), estudie y compile el siguiente ejemplo, manipu05.cpp,
adems experimente con las banderas no incluidas en el programa, estoy seguro
que no presentar problema alguno comprender el uso de las diferentes banderas.

//***********************************************
// manipu05.cpp
//***********************************************

#include <iostream.h>
#include <iomanip.h>

int main()
{
int numero;

cout << "Introduzca un numero:\n";
cin >> numero;
cout << "El valor introducido en base 10 es: " << numero
<< endl;
cout << setiosflags(ios::oct);
cout << "en base octal es: " << numero << endl;
cout << setiosflags(ios::hex);
cout << "y en base hexadecimal es: " << numero << endl;
cout << setiosflags(ios::uppercase|ios::showbase);
cout << "utilizando los manipuladores uppercase y showbase"
" el valor es: " << numero << endl;
cout << resetiosflags(ios::hex);
cout << "Ahora el valor se representa en base octal asi: "
<< numero << endl;
cout << resetiosflags(ios::uppercase|ios::showbase|ios::oct);
cout << setiosflags(ios::showpos|ios::showpoint|ios::fixed);
cout << "Ahora el valor es: " << (float)numero << endl;

cout << resetiosflags(ios::showpos|ios::showpoint|
ios::fixed);

cout << "El valor es " << numero << endl;
return 0;
}
El programa manipu05.cpp empieza solicitndole un nmero el cual es
desplegado inmediatamente para demostrar los ajustes predeterminados para los
flujos de E/S, despus se utiliza la bandera oct para representar el valor introducido
en base octal, luego de mostrar el valor en pantalla se vuelve a utilizar la bandera
hex sta vez para mostrar el nmero introducido en base hexadecimal. En sta
parte del programa, lnea 19, es conveniente hacer notar que hemos modificado
dos veces la representacin que deseamos darle a los flujos de E/S, en ste orden,
primero indicamos que deseamos la base octal y posteriormente la base
hexadecimal, si despus de la lnea 19 utilizamos el manipulador
setiosflags(ios::oct) la representacin de los flujos de E/S no ser en base octal
sino en hexadecimal, entonces, si deseamos nuevamente la representacin del
valor numrico introducido en base octal necesitamos reestablecer la bandera oct
anteriormente establecida en la lnea 15, para esto utilizamos el manipulador
resetiosflags() como est ilustrado en la lnea 23 y posteriormente en las lneas 26
y 29 del programa. Cuando sea necesario especificar varias banderas podemos
hacer uso del operador OR tanto con el manipulador setiosflags() como con
resetiosflags() tal y como se puede apreciar en las lneas 20, 26, 27 y 30 del
programa.
Volver al principio

Funciones de salida
Sabemos que un programa C++ utiliza el operador de insercin (<<) para
mostrar datos de salida, tambien que el flujo de salida cout est definido como una
clase y por lo tanto contiene ciertas funciones, llamadas miembro. En los
programas que hemos visto hasta ste momento utilizamos el flujo de salida cout
en conjunto con el operador de insercin << para mostrar datos de salida, sin
embargo podemos hacer uso de las funciones miembro de salida definidas para el
flujo cout en caso de necesitar un control ms preciso, las funciones principales
para el flujo de salida estn definidas en el archivo ostream.h. Analizando ste
archivo de cabecera podemos ver las funciones mencionadas, pero adems
podemos apreciar que la clase ostream est derivada de la clase ios y por lo tanto
tambien podemos utilizar con los flujos de salida las funciones propias de la clase
ios. Recuerde que en la siguiente leccin trataremos el tema de las clases, por lo
pronto es bueno que empiece a familiarizarse con la terminologa de la
programacin en C++. Veamos un ejemplo de las funciones miembro de cout
llamadas put y write.

//***********************************************
// salida01.cpp
//***********************************************

#include <iostream.h>

int main()
{
int letra;
char letras[]="Programacion en C++ por Virgilio"
"Gomez Negrete";

for(letra='A'; letra <= 'Z'; letra++)
{
cout << letra << " ";
}
cout << "\n\n";

for(letra='A'; letra <= 'Z'; letra++)
{
cout.put((char)letra);
cout << " ";
}
cout << "\n\n";

cout.write(letras, 21);
cout << endl;

return 0;
}
El programa contiene dos bucles que demuestran la diferencia entre utilizar la
funcin miembro put versus el mecanismo tradicional cout <<. Observe que hemos
declarado una variable de tipo int llamada letra, por sta razn el primer bucle
despliega las letras del alfabeto, slo que en sus respectivos equivalentes decimales
del cdigo ASCII. El segundo bucle es prcticamente igual al primero excepto por el
uso de la funcin miembro de la clase ostream llamada put que de acuerdo a su
definicin, su argumento debe ser de tipo char, por lo tanto debemos moldear
nuestra variable de tipo int para que sea ahora de tipo char y as poder utilizarla en
la funcin miembro put. Habr notado que para tener acceso a una funcin
miembro de una clase utilizamos el operador punto (.). Ya en la parte final del
programa encontramos un ejemplo del uso de la funcin miembro llamada write,
sta despliega el nmero indicado de carcteres, en ste caso 21, empezando por
el principio del arreglo de tipo char llamado letras. Estudiando el archivo de
cabecera ostream.h podemos determinar las funciones miembro de la clase
ostream y sus respectivos argumentos, comparando sta informacin con los
ejemplos aqu presentados nos ayudar a entender la manera en que se relacionan
las definiciones de las diferentes funciones con sus aplicaciones reales, prctica que
recomiendo ampliamente.
En el programa manipu05.cpp analizamos diferentes especificaciones de
banderas que establecimos mediante el uso del manipulador setiosflags(), pues
bien, podemos utilizar la funcin miembro setf() para realizar la misma funcin que
con el manipulador setiosflags() y en forma similar, podemos utilizar la funcin
unsetf() para los mismos propsitos que el manipulador resetiosflags(), incluso es
posible combinar diferentes especificaciones de bandera mediante el uso del
operador OR, ms interesante an es que podemos utilizar la funcin miembro
flags() para determinar el estado original de las banderas de flujo de E/S, guardar
el dato en una variable y posteriormente utilizarlo para restituir la condicin original
de operacin de las banderas de flujo, como lo demuestra el siguiente programa,
llamado salida02.cpp

//***********************************************
// salida02.cpp
//***********************************************

#include <iostream.h>
#include <iomanip.h>

int main()
{
long banderas_originales;
int numero=64;

banderas_originales=cout.flags();
cout << "banderas originales es: " << cout.flags() << endl;
cout.setf(ios::showbase|ios::uppercase|ios::hex);
cout << "banderas modificadas es: " << cout.flags() << endl;
cout << "la variable numero en base 16 es: "
<< numero << endl;
cout.flags(banderas_originales);
cout << "restituidas las banderas originales, \nahora "
"la variable numero en base 10 es: " << numero << endl;
cout << "banderas originales es: " << cout.flags() << endl;

return 0;
}
Se aprecia cmo el uso adecuado de las funciones miembro puede simplificar un
cdigo fuente y hacer el programa ms eficiente, sta es una buena razn para
tomarse un tiempo y examinar los diferentes archivos de cabecera incluidos con
nuestro compilador, de pasada respondemos a la pregunta Qu archivos de
cabecera debo utilizar en mi programa? Muy importante es familiarizarse con la
documentacin incluida en el compilador que utilicemos, adems es una buena
prctica como programador.
Volver al principio

Funciones de entrada
Para Usted no debe ser ya cosa extraa que en C++ utilizamos el operador de
extraccin (>>) en conjunto con el flujo cin para realizar operaciones de entrada. El
flujo de entrada cin tambien est definido como una clase y su declaracin la
encontramos en el archivo de cabecera istream.h junto con sus respectivas
funciones miembro, algunas de las cuales analizaremos en el siguiente programa,
llamado entrada.cpp, sin duda alguna no tendr problema en comprender lo
expuesto en el siguiente cdigo:

//***********************************************
// entrada.cpp
//***********************************************

#include <iostream.h>
#include <ctype.h>

int contador; // automticamente inicializada en cero

int main()
{
char texto[64], letra;

cout << "Teclee una linea de texto y presione enter\n\n";
cin.getline(texto, sizeof(texto));
cout << "\n\nEl texto introducido es:\n\n" << texto
<< "\n" << "el cual contiene " << cin.gcount()-1
<< " carcteres" << endl;
cout << "\n\nTeclee otra linea de texto que incluya una x\n";

do
{
letra=cin.get();
cout << (char)toupper(letra);
contador++;
}
while(letra!='x');
cout << "\n\nUsted escribio " << contador-1 << " carcteres "
"antes de la x" << endl;

return 0;
}
No est de ms recordar que una variable de tipo global es automticamente
inicializada a cero. El programa entrada.cpp demuestra el uso de algunas funciones
miembro de la clase istream, empezando por la funcin llamada getline() que lee
una lnea de texto hasta encontrar un carcter de retorno de carro ("\n"),
similarmente se hace uso de la funcin miembro gcount() para determinar el
nmero de carcteres ledos, sta funcin incluye el carcter de retorno de carro,
por lo tanto restamos uno al valor retornado por la funcin para que el resultado
desplegado sea el correcto (lnea 17). En la segunda parte del programa se utiliza
la funcin miembro llamada get(), sta lee un solo carcter borrndolo de la
memoria de almacenamiento temporal, se convierte a mayscula utilizando la
funcin toupper() moldeando la salida de sta a tipo char y se despliega el
resultado en pantalla. ste proceso se repite merced de un bucle do-while hasta
encontrar un carcter 'x'. Compare el resultado obtenido de la cuenta efectuada en
el bucle do-while por la variable llamada contador con el resultado obtenido al
utilizar la funcin miembro gcount().
Es importante experimentar con lo expuesto en ste captulo, con frecuencia
aprendemos detalles que por alguna causa nos pasan inadvertidos con la simple
lectura del texto, adems cada compilador tiene sus detalles particulares que
conviene conocer para conseguir el mximo provecho del mismo.
Volver al principio


Emulacin de conio de Borland para Dev-C++
Por qu emular conio?
Aunque se trate de una librera no estndar, conio se ha convertido para muchos
programadores educados o acostumbrados a compiladores de Borland en una
herramienta imprescindible para crear programas de consola.
Adicionalmente, cuando se crean aplicaciones de consola usando compiladores para
Windows, como Dev-C++, a menudo necesitamos compilar programas escritos
originalmente para compiladores Borland. O sencillamente, queremos dotar a nuestros
programas de consola de una apariencia ms amigable y agradable.
Por supuesto, podemos recurrir a las funciones de consola del API de Windows, pero a
menudo la conversin entre funciones de conio y sus equivalentes en el API no son tan
sencillas, y en cualquier caso requiere cierto tiempo.
Este documento incluye una emulacin de conio para el compilador Mingw, usado por
el entorno de programacin Dev-C++.
Es cierto que Dev-C++ incluye una emulacin de conio, pero a nuestro juicio no es lo
bastante fiel en cuanto a comportamiento a la original de Borland. Sobre todo en
funciones de ventanas, lecturas sin eco en pantalla, y en funciones como "kbhit", que o
bien no se emulan, o se hace de forma incompleta.
Por supuesto, no todas las funciones y macros se han emulado, hay algunas con las que
no es posible hacerlo, concretamente las que relacionadas con entrada y salida de
puertos: "inp", "inport", "inportb", "inpw", "outp", "outport", "outportb" y "outpw"; ya
que estas macros colisionan con el control del hardware de Windows.
Adems de estas macros, la nica funcin que no se emula es "cscanf", debido a las
dificultades que entraa su implementacin. En futuras versiones intentaremos incluirla.
En su lugar se usa "scanf" directamente.
Trabajar con la emulacin de conio
Al contrario que sucede con los compiladores de Borland, en el que la librera est
includa en el compilador, cuando se trabaja con otros compiladores es necesario incluir
el cdigo objeto en la fase de enlazado o bien el fichero fuente conio.c como parte del
proyecto. Tambin se puede crear una librera esttica (ver creacin de libreras
estticas), que es lo que haremos en este artculo.
Esto es algo ms engorroso que cuando se usa desde un compilador de Borland, pero
no debemos olvidar que no se trata de una librera estndar, cosa que a menudo se
olvida o pasa desapercibida para los que estn acostumbrados a usarla.
En la seccin de libreras de Borland se incluye una referencia de las funciones,
macros y estructuras definidas en conio.
Como recordatorio, he incluido el texto de ayuda de Borland para cada una de las
funciones emuladas dentro del propio fichero fuente.
Ficheros incluidos
Se suministran tres proyectos "dev", cada uno orientado a una forma diferente de usar la
librera.
El primer proyecto se llama "conio-lib", y sirve para crear un fichero de librera esttica,
"conio.a".
Aconsejo compilar primero ese proyecto, el resultado ser el fichero "libconio.a". Una
vez hecho esto habra que copiar el fichero "libconio.a" al directorio "C:\Dev-Cpp\lib",
suponiendo que tengas instalado Dev-C++ en el disco "C:". Despus, habra que copiar
los ficheros "conio.h" y, opcionalmente, "conio.c" en el directorio "C:\Dev-
Cpp\include".
Ahora podemos compilar cualquiera de los otros proyectos.
El proyecto "conio-eje-a" es un ejemplo para el uso de la librera esttica, en l se aade
el fichero "libconio.a" a la lista de libreras a incluir en la fase de enlazado.
El proyecto "conio-eje-c" es un ejemplo para el uso del fichero "conio.c" como parte de
un proyecto con varios ficheros fuente.
En el fichero zip que se puede descargar al final de esta pgina, se incluyen diez
ficheros:
conio.h: el fichero de cabecera, con las declaraciones de funciones y tipos.
conio.c: el fichero fuente de la emulacin.
libconio.a: el fichero de librera.
text.c: un fichero de ejemplo del uso de "conio".
conio-lib.dev: proyecto para la generacin del fichero de librera.
conio-eje-a.dev: proyecto para ilustar un ejemplo usando el fichero de librera.
conio-eje-c.dev: proyecto para ilustrar un ejemplo usando el fichero fuente como
parte de un proyecto multifuente.
6-Console_conio.template, ConsoleConio_c.txt y ConsoleConio_cpp.txt: deben
copiarse al directorio "c:\dev-cpp\Templates", y sirven para crear un nuevo tipo de
proyecto Dev-C++, que facilita la creacin aplicaciones para consola usando "conio".
Programa de ejemplo
Se trata de un programa muy sencillo que hace uso de las funciones ms frecuentes de
conio: "clrscr", "gotoxy", "cputs", "putch", "getch", "getche", "kbhit", etc.
Errores e implementaciones incorrectas
Por supuesto, es posible que algunas de las funciones tengan errores, o que su
comportamiento no sea exactamente el esperado. En cualquier caso, si detectas un error
o algn comportamiento extrao, notifcanoslo a colabora@conclase.net e intentaremos
corregirlo en futuras versiones.
Del mismo modo, si tu mismo decides modificar, mejorar o corregir alguna funcin,
con gusto incluiremos tus modificaciones en futuras versiones, por supuesto, indicando
tu autora dentro del propio fichero fuente tanto como en este documento.
Historia de versiones
La versin 1.1, se debe a la colaboracin de un compaero, que ha corregido los errores
que comet al usar caractersticas C++ en el fichero conio.c.
La versin 1.2 contiene una correcin sobre la funcin _setcursortype, que no
funcionaba correctamente con la opcin _NOCURSOR. Gracias a Antonio Vallejo Zea
por indicarnos el error.
La versin 1.3 est corregida para generar el fichero de librera con el nombre
"libconio.a", de modo que es ms fcil de usar, ya que basta con especificar la opcin de
enlazado "-lconio".
Tambin se incluye un nuevo tipo de proyecto para Dev-C++: "consola + conio", que
facilita la creacin de proyectos para consola que usen esta librera.
La versin 1.31 corrige un error en la funcin kbhit. En determinados casos, cuando los
caracteres son ledos demasiado rpido despus de una llamada a kbhit, el evento de
tecla soltada llega despus de la lectura, y se producen detecciones falsas al tomar el
evento de tecla soltada como un nuevo evento de teclar. Se ha corregido el error para
que slo se consideren los eventos de tecla pulsada. Gracias a David por notificar el
error.
Mejoras (caractersticas a aadir)
An quedan cosas por mejorar, y estamos trabajando en ellas. Por ejemplo, la respuesta
a teclas especiales: las de funcin y las del cursor. Para ello hay que cambiar la
implementacin de las funciones de lectura: getch, getche... de modo que usen la
funcin del API ReadConsoleInput.


math.h es un archivo de cabecera de la biblioteca estndar del lenguaje de
programacin C diseado para operaciones matemticas bsicas. Muchas de sus
funciones incluyen el uso de nmeros en coma flotante. C++ tambin implementa estas
funciones por razones de compatibilidad y las declara en la cabecera cmath.
Todas las funciones en las que participan ngulos toman y devuelven radianes.
Funciones miembro anteriores al C++ [editar]
Nombre Descripcin
acos arcocoseno
asin arcoseno
atan arcotangente
atan2 arcotangente de dos parmetros
ceil menor entero no menor que el parmetro
cos coseno
cosh coseno hiperblico
exp(double x) funcin exponencial, computa e
x

fabs valor absoluto
floor mayor entero no mayor que el parmetro
fmod resto del punto flotante
frexp fracciona y eleva al cuadrado.
ldexp tamao del exponente de un valor en punto flotante
log logaritmo natural
log10 logaritmo en base 10
modf obtiene un valor en punto flotante ntegro y en partes
pow(x,y) eleva un valor dado a un exponente, x
y

sin seno
sinh seno hiperblico
sqrt raz cuadrada
tan tangente
tanh tangente hiperblica




Funciones y
Libreras"
Programacin C
Alberto Pacheco
apacheco@itchihuahua.edu.mx
(12/Mar/2007 3:02pm)

Presentacin hecha en ExpoVision, Alberto Pacheco, Ver 1.0.50, MEXICO
D.R. 2009

ITCH Programacin C: "Funciones y Libreras"
Contenido
[Inicio] [Final]

Atrs Sig
Mapa Conceptual
1. Funcin: Introduccin
2. Declarar, Definir, Llamar
4. Adivina v2.0
5. Libreras
6. Librera de Adivina v3.0
7. Adivina v3.0
S u g e r e n c i a s
(1/7) ITCH Programacin C: "Funciones y Libreras"
Funcin: Introduccin
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ask] [CSS]
Funcin: Toda funcin regresa un
valor. Una funcin es anloga a un
comando del lenguaje, pero definido por el
programador
Programa: Conjunto de funciones, mnimo
funcin main()
Librera: Conjunto de funciones sin funcin
main()
Ventajas Funciones:
1. Elimina redundancia y ahorra espacio
memoria (ventaja histrica)
2. Estructura y organiza cdigo,
i.e. herramienta conceptual,
e.g. programacin genrica
3. Facilita mantenimiento y localizacin de
errores
4. Promueve reuso de cdigo, e.g. libreras
5. Divisin trabajo equipos desarrolladores
(2/7) ITCH Programacin C: "Funciones y Libreras"
Declarar, Definir, Llamar
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ask] [CSS]
Funcin: es analoga a un comando
del lenguaje, pero definido por el
programador
Declaracin: perfil informa existencia
funcin posteriormente definida
Definicin: implementacin o cdigo actual
de la funcin
Invocacin o Llamada: ejecuta una funcin
previamente definida
Anatoma de una Funcin:
Cabeza o Perfil: [resultado] [nombre-
funcin]( [parmetros] )
Cuerpo o Bloque: { [decl-var] [sentencias]
[resultado] }
(3/7) ITCH Programacin C: "Funciones y Libreras"
Declarar, Definir, Llamar
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ask] [CSS]
int mayor(int, int); // Declaracin

int mayor(int x, int y) // Definicin
{
return x > y? x : y;
}

main()
{
int c = mayor(3,6); // Llamada
printf("Mayor=%d",c);
}
(4/7) ITCH Programacin C: "Funciones y Libreras"
Adivina v2.0
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ask] [CSS]
//ADIVINA2.C (VERSION 2.0)

#include <stdio.h> // printf scanf
#include <stdlib.h> // rand srand
#include <time.h> // time

#define MAX_NUM 1000 // limite superior
#define MAX_OP 15 // intentos

int azar(int mn, int mx)
{
srand(time(0));
return mn + rand() % mx;
}

int input(int i, char *txt)
{
int num;
printf("\n%d) %s? ",i,txt);
scanf("%d", &num);
return num;
}

char confirm(char *txt)
{
char ok;
printf("\n\n%s (S/N)?",txt);
scanf("%*c%c", &ok);
return (ok=='s' || ok=='S');
}

main()
{
do // inicio-juego
{
int num, i, oculto=azar(1,MAX_NUM);
printf("\n\nADIVINA NUMERO 1 - %d",MAX_NUM);
printf("\nEN %d OPORTUNIDADES\n",MAX_OP);
for ( i=1; i<MAX_OP; i++ ) // ciclo-juego
{
num = input(i,"Anota un numero");
if ( num <= 0 ) return 1;
if ( num == oculto ) {
printf("\n\nFELICIDADES! GANASTE EN %d INTENTOS",i);
break;
}
if ( num > oculto )
printf("\nANOTA UN NUMERO menor");
else
printf("\nANOTA UN NUMERO MAYOR");
} // un-juego
if ( num != oculto )
printf("\n\nAGOTASTE OPORTUNIDADES. NUMERO=%d",oculto);
} while( confirm("Deseas volver a jugar") ); // reiniciar
puts("\nBye bye..");
return 0;
}
(5/7) ITCH Programacin C: "Funciones y Libreras"
Libreras
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ref] [Ask] [CSS]
Librera: Conjunto de funciones, que a
diferencia de un programa de Lenguaje C,
no contiene la funcin main()
Libreras Estndard: Todo compilador
que soporte ANSI C contiene al menos las
siguientes libreras
Archivos encabezado (Header file):
Cdigo de lenguaje C que corresponde a
declaraciones y recursos de una librera,
que sern asociados mediante la directiva
#include
Tabla 1. Libreras Bsicas de Lenguaje C
Manejo de
caracteres
Funciones
Matemticas
E/S
Bsico
ctype.h math.h stdio.h
Miscelaneos
Manejo de
cadenas
Fecha y
hora
stdlib.h string.h time.h
(6/7) ITCH Programacin C: "Funciones y Libreras"
Librera de Adivina v3.0
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ref] [Ask] [CSS]
//ADIVINA.H (VERSION 3.0)

#include <stdio.h> // printf scanf
#include <stdlib.h> // rand srand
#include <time.h> // time


int azar(int mn, int mx)
{
srand(time(0));
return mn + rand() % mx;
}


int input(int i, char *txt)
{
int num;
printf("\n%d) %s? ",i,txt);
scanf("%d", &num);
return num;
}


char confirm(char *txt)
{
char ok;
printf("\n\n%s (S/N)?",txt);
scanf("%*c%c", &ok);
return (ok=='s' || ok=='S');
}
(7/7) ITCH Programacin C: "Funciones y Libreras"
Adivina v3.0
[Inicio] [Final]


Atrs Sig
<< [1] [2] [3] [4] [5] [6] [7] >> [Ref] [Ask] [CSS]
//ADIVINA3.C (VERSION 3.0)

#include "adivina.h" // azar, input, confirm

#define MAX_NUM 1000 // limite superior
#define MAX_OP 15 // intentos

main()
{
do { // inicio-juego
int num, i, oculto=azar(1,MAX_NUM);
printf("\n\nADIVINA NUMERO 1 - %d",MAX_NUM);
printf("\nEN %d OPORTUNIDADES\n",MAX_OP);
for ( i=1; i<MAX_OP; i++ ) // ciclo-juego
{
num = input(i,"Anota un numero");
if ( num <= 0 ) return 1;
if ( num == oculto ) {
printf("\n\nFELICIDADES! GANASTE EN %d INTENTOS",i);
break;
}
if ( num > oculto )
printf("\nANOTA UN NUMERO menor");
else
printf("\nANOTA UN NUMERO MAYOR");
} // un-juego
if ( num != oculto )
printf("\n\nAGOTASTE OPORTUNIDADES. NUMERO=%d",oculto);
} while( confirm("Deseas volver a jugar") ); // reiniciar
puts("\nBye bye..");
return 0;
}

You might also like