miércoles, 27 de febrero de 2008

¿Cuál es la diferencia en C++ entre usar "\n" y endl?

La diferencia está en que al usar endl se invoca automáticamente a flush y "\n" no.

Cómo implementar la funcion getch(), readkey, getchar() para C++

El siguiente post explica como implementar una función getch() al estilo getchar() de Pascal o getche() de conio.h.

Creamos un fichero al que yo llamé Stflib.h ( debido a que incluyo otras funciones como ToString, Gotoxy, que puedes ver en este blog en el menú).

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cstdlib>
 
using namespace std;

static bool isGenerated = false;

const string readCharScript[7] = {"#!/bin/sh" ,
"tput smso",
"tput rmso",
"oldstty=`stty -g`",
"stty -icanon min 1 time 0",
"dd bs=1 count=1 of=output >/dev/null 2>&1",
"stty \"$oldstty\"" };

void GenereFile() {
ofstream outputFile( ".readone", fstream::out );
for ( int i = 0; i < 7; i++ ) outputFile << readCharScript[i] << endl; system("chmod +x .readone"); isGenerated = true; } char getch() { if (!isGenerated) GenereFile(); system("./.readone"); char ch; ifstream file("output", fstream::in); file >> ch;
file.close();
return ch;
}



En otro fichero, al que llamé getch.C, ponemos:


#include "Stflib.h"

using namespace std;

int main() {
char ch = getch();
cout << endl << "El caracter es: " << ch << endl; return 0; }

lunes, 25 de febrero de 2008

¿Por qué se usa m_ como prefijo en los atributos privados de la clase en C++ y otros lenguajes?

En los atributos privados muchos programadores anteponen el prefijo m_ al atributo. Esto se hace para saber distinguir las variables de la clase de las que no lo son. La m viene de member variable.
En los atributos protegidos se utiliza m_p.

viernes, 22 de febrero de 2008

How to convert float to int in c++

Let's use static_cast.


float foo = 3.4; // Here the float variable
int myint = static_cast<int>(foo); // Now we have the int part of foo in myint


I hope I had helped you. If you want, you can post your comments and I'll answer you as soon as possible. Thanks!

Cómo convertir un float a un int en c++

Para convertir un int a float utilizamos static_cast de la siguiente manera:
float foo = 3.4;
int myint = static_cast<int>(foo);
Y ahora ya tenemos en la variable myint el valor 3.
Espero que les haya servido de ayuda. Pueden postear comentarios si lo desean o proponer una alternativa.

jueves, 21 de febrero de 2008

Crear una barra de progreso para la consola de Linux en C++.

Un ejemplo de cómo programar una barra de progreso para utilizarla en la consola de Linux.


Primero creamos el fichero Stflib.h
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

/**
 * Función para convertir cualquier tipo de datos a string.
 */
template <class T>
inline string ToString(const T& t) {
  stringstream ss;
  ss << t;
  return ss.str();
}

/**
 * Función para emular al gotoxy en la consola de Linux.
 */
inline string Gotoxy(const int& x, const int& y) {
  return "\33[" + ToString(x) + ";" + ToString(y) + "H";
}
Segundo creamos el fichero Colors.h
/** \file   Colors.h
*  \brief  Declaraciones de la clase \c Colors.
*  \author Airam Rodríguez Rivero.
*  \date   11-11-07
*  El propósito de esta clase es la de permitir la utilización de colores
*  utilizando la consola de linux que será donde se envíe el flujo de datos
*  generado por nuestro programa.
*/

#ifndef _COLORS_H_
#define _COLORS_H_


#include <string>
#include <iostream>

using namespace std;

typedef string     TColor;

const TColor Reset     = "\033[0m";    // Reset
const TColor Bold      = "\033[1m";    // Brillo o negrita.
const TColor Underline = "\033[4m";    // Subrayado

// ******************* Foreground Non-lighted Colors *******************

const TColor Black     = "\033[30m";   // Negro
const TColor Red       = "\033[31m";   // Rojo
const TColor Green     = "\033[32m";   // Verde
const TColor Brown     = "\033[33m";   // Marron
const TColor Blue      = "\033[34m";   // Azul
const TColor Magenta   = "\033[35m";   // Magenta
const TColor Cyan      = "\033[36m";   // Cyan
const TColor White     = "\033[37m";   // Blanco

// ******************* Foreground Lighted Colors *******************

const TColor HBlack    = "\033[1m\033[30m"; /// bright/bold black
const TColor HRed      = "\033[1m\033[31m"; /// b red
const TColor HGreen    = "\033[1m\033[32m"; /// b green
const TColor HYellow   = "\033[1m\033[33m"; /// b yellow
const TColor HBlue     = "\033[1m\033[34m"; /// b blue
const TColor HMagenta  = "\033[1m\033[35m"; /// b pink
const TColor HCyan     = "\033[1m\033[36m"; /// b cyan
const TColor HWhite    = "\033[1m\033[37m"; /// b white

// ******************* Background Non-lighted Colors *******************

const TColor BBlack    = "\033[40m";   // Negro
const TColor BRed      = "\033[41m";   // Rojo
const TColor BGreen    = "\033[42m";   // Verde
const TColor BBrown    = "\033[43m";   // Marron
const TColor BBlue     = "\033[44m";   // Azul
const TColor BMagenta  = "\033[45m";   // Magenta
const TColor BCyan     = "\033[46m";   // Cyan
const TColor BWhite    = "\033[47m";   // Blanco

// ******************* Background Lighted Colors *******************

const TColor HBBlack   =  "\033[40;1m";   // Negro
const TColor HBRed     =  "\033[41;1m";   // Rojo
const TColor HBGreen   =  "\033[42;1m";   // Verde
const TColor HBBrown   =  "\033[43;1m";   // Marron
const TColor HBBlue    =  "\033[44;1m";   // Azul
const TColor HBMagenta =  "\033[45;1m";   // Magenta
const TColor HBCyan    =  "\033[46;1m";   // Cyan
const TColor HBWhite   =  "\033[47;1m";   // Blanco

#endif
Tercero creamos el fichero ProgressBar.h
/** \file   ProgressBar.h
*  \brief  Declaraciones de la clase \c ProgressBar.
*  \author Airam Rodríguez Rivero.
*  \date   21-02-08
*  La clase ProgressBar permite generar barras de progreso para la
*  consola de Linux. Se puede determinar el color de fondo de la barra
*  de progreso ( el parámetro _background ), el color de progreso cargado
*  ( el parámetro _loadedColor ), el caracter de relleno de la barra de 
*  progreso que por defecto es un espacio en blanco. Se especifica la
*  posición en la pantalla donde se va a colocar la barra de progreso mediante
*  el atributo _coordinate.
*/

#ifndef _PROGRESSBAR_H_
#define _PROGRESSBAR_H_

#include <iostream>
#include <string>
#include "Stflib.h"

using namespace std;

typedef short int            TProgress;
typedef short int                TSize;
typedef string                  TColor;
typedef pair TCoordinate;
typedef char                 TFillChar;

/// Clase para manejar barras de progreso en la consola de linux.
class ProgressBar {
private:
TProgress         _loaded;    // Representa el porcentaje cargado en la barra de progreso.
TSize               _size;    // Tamaño de la barra de progreso.
TColor        _background;    // Color de fondo de la barra de progreso.
TColor       _loadedColor;    // Color del porcentaje cargado.
TCoordinate   _coordinate;    // Posición en la que presentar en pantalla la barra de progreso.
TFillChar       _fillChar;    // Carácter de relleno de la barra de progreso.
bool   _percentageVisible;
public:
ProgressBar( const TSize& s, const TColor& bg, const TColor& lc, const TFillChar& fc = ' ' ) : _size( s ), _background( bg ), _loadedColor( lc ), _fillChar( fc ), _percentageVisible( true ) { }
~ProgressBar() { }

inline void SetBackground( const TColor& color ) { _background  = color; }
inline void SetLoadedColor( const TColor& color ) { _loadedColor = color; }
inline void SetSize( const TSize& size ) { _size        = size; }
inline void SetCoordinate ( const TCoordinate& coordinate ) { _coordinate  = coordinate; }
inline void SetLoaded( const TProgress& progress )  { _loaded      = progress; }
inline void SetPercentageVisible( const bool& v ) { _percentageVisible = v; }

inline TSize GetX() const { return _coordinate.first;  }
inline TSize GetY() const { return _coordinate.second; }
inline TSize GetSize() const { return _size; }

inline bool IsPercentageVisible() const { return _percentageVisible; }

inline TProgress GetLoaded() const { return _loaded; }

inline TColor GetBackground() const  { return _background;  }
inline TColor GetLoadedColor() const { return _loadedColor; }
inline TFillChar GetFillChar() const { return _fillChar; }

void ShowPercentage( ostream& sout ) const;
void Paint( ostream& sout ) const;

friend ostream& operator<<( ostream& sout, const ProgressBar& pb ); };  #endif  
Cuarto: Creamos el fichero ProgressBar.C
#include "ProgressBar.h"
#include "Colors.h"

using namespace std;

void ProgressBar::ShowPercentage( ostream& sout ) const {
  if ( IsPercentageVisible() ) {
    sout << "[" << GetLoaded() << "%] ";
  }
}

void ProgressBar::Paint( ostream& sout ) const {
  sout << Gotoxy( GetX(), GetY() );
  // Calculamos el número de caracteres con los que rellenamos la barra de progreso.
  float charged = GetLoaded() * GetSize() / 100;
  TSize partialSize = static_cast(charged);
  for ( TProgress i = 0; i <= partialSize; i++ )
    sout << GetLoadedColor() << GetFillChar();
  for ( TProgress i = partialSize; i < GetSize(); i++ )
    sout << GetBackground() << ' ';
  sout << Reset;
  ShowPercentage( sout );
}

ostream& operator<<( ostream& sout, const ProgressBar& pb ) {
  pb.Paint( sout );
  return sout;
}
Quinto: Probamos nuestra barra de progreso con el fichero ProgressBarTest.C
#include <iostream>
#include <time.h>
#include <cstdlib>
#include "ProgressBar.h"
#include "Colors.h"

using namespace std;

int main() {
  //system("clear"); // Importante para no sobreescribir la pantalla.
  // Emular goto(x, y);
  TProgress completed = 10;
  ProgressBar pb( completed, HBWhite, BBlue, ' ' );
  TCoordinate c;
  c.first = 6;
  c.second = 10;
  pb.SetCoordinate(c);
  TProgress i = 0;
  time_t lastTime = time( NULL );
  while ( i <= 10 ) {
    if ((difftime(time(NULL), lastTime)) >= 0.55) {
      cout << Reset; // Importante poner este reset separado, sino tira error de segmentación. 
      system("clear");
      lastTime = time (NULL);
      pb.SetLoaded(i * 10);
      cout << pb;
      cout << flush;
      i++; 
    } else 
      lastTime = time(NULL);
  }
  cout << Reset << endl; // Importante poner este reset separado, sino tira error de segmentación. 
}  
La compilación de todo el código sería:
g++ Stflib.h
g++ Colors.h
g++ ProgressBar.h
g++ -c ProgressBar.C
g++ -o bar ProgressBar.o ProgressBarTest.C
Y ahora para ejecutar:
./bar
Espero que les sirva y que les guste. Pueden dejar comentarios por si tienen dudas o si quieren que cambie alguna cosa! Muchas gracias!!

jueves, 14 de febrero de 2008

¿Cómo implementar la función gotoxy en C++ para la consola de Linux?

Una manera de implementar la función goto(x,y) en C++ que permite escribir texto en una posición determinada en la consola de Linux.
/** \file   GotoXY.C
*  \brief  Definición de las funciones necesarias para implementar gotoxy.
*  \author Airam Rodríguez Rivero
*  \date   14-02-08
*/
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
using namespace std;

/**
 * Función para convertir cualquier tipo de datos a string.
 */
template <class T>
inline string ToString(const T& t) {
  stringstream ss;
  ss << t;
  return ss.str(); 
} 
/** Función para emular al gotoxy en la consola de Linux. */
inline string gotoxy(const int& x,const int& y) {
  return "\33[" + ToString(x) + ";" + ToString(y) + "H"; 
}

int main() {
  system("clear"); // Importante para no sobreescribir la pantalla.
  // Emular goto(x, y);
  cout << gotoxy(2,4) << "Hola" << endl;
}