<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>4 bits blog &#187; C/C++</title>
	<atom:link href="http://blog.4bits.es/category/lenguajes/c-cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.4bits.es</link>
	<description>Ahora en 16 colores</description>
	<lastBuildDate>Thu, 05 Aug 2010 13:52:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Detectar fugas de memoria en Visual Studio</title>
		<link>http://blog.4bits.es/detectar-fugas-de-memoria-en-visual-studio/</link>
		<comments>http://blog.4bits.es/detectar-fugas-de-memoria-en-visual-studio/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 11:58:51 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=480</guid>
		<description><![CDATA[Para los que programen en C con Visual Studio y sientan añoranza de valgrind, aquí están los pasos sobre cómo detectar fugas de memoria (memory leaks) en Visual Studio: Añadir la macro _CRTDBG_MAP_ALLOC del preprocesador, ya sea definiéndola en algún archivo del proyecto o en las opciones de compilación del proyecto. Incluir en el siguiente [...]]]></description>
			<content:encoded><![CDATA[<p>Para los que programen en C con Visual Studio y sientan añoranza de <a href="http://valgrind.org/">valgrind</a>, aquí están los pasos sobre <strong>cómo detectar fugas de memoria (<em>memory leaks</em>) en Visual Studio</strong>:</p>
<ul>
<li>Añadir la macro <code>_CRTDBG_MAP_ALLOC</code> del preprocesador, ya sea definiéndola en algún archivo del proyecto o en las opciones de compilación del proyecto.</li>
<li>Incluir en el siguiente orden <code>stdlib.h</code> y <code>crtdbg.h</code> en los archivos dónde se busquen las fugas de memoria. El archivo <code>crtdgb.h</code> sustituye las funciones <code>malloc</code> y <code>free</code> por unas propias que registran la memoria reservada y liberada.</li>
<li>Añadir la función <code>_CrtDumpMemoryLeaks ()</code> al final del programa en el que se buscan las fugas de memoria. Esta función muestra por la salida de depuración las fugas de memoria detectadas.</li>
</ul>
<p>Todo <strong>esto sólo funcionará cuando el proyecto se compile con la macro <code>_DEBUG</code> definida</strong>, es decir, en lo que debería ser para todos la versión de depuración del programa.</p>
<p>La macro <code>_CRTDBG_MAP_ALLOC</code> sirve para que la función <code>_CrtDumpMemoryLeaks ()</code> muestre información sobre el archivo y la línea en la que se produjo la fuga de memoria.</p>
<p>Un pequeño ejemplo de cómo quedaría todo:</p>
<pre class="brush:c">#define _CRTDBG_MAP_ALLOC
#include &lt;stdlib.h&gt;
#include &lt;crtdbg.h&gt;

int
main (int argc, char *argv[])
{
    /* Código del programa */

    _CrtDumpMemoryLeaks ();

    return 0;
}</pre>
<p>Si este programa tuviera alguna fuga de memoria, al compilarlo en modo depuración y ejecutar el depurador de Visual Studio, se obtendría en la salida de éste un listado con las fugas de memoria del programa.</p>
<p>Para más información, leed el artículo <a href="http://msdn.microsoft.com/en-us/library/e5ewb1h3(v=VS.80).aspx">Enabling Memory Leak Detection</a> de la MSDN.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/detectar-fugas-de-memoria-en-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mini, una biblioteca para procesar archivos INI</title>
		<link>http://blog.4bits.es/mini-una-biblioteca-para-procesar-archivos-ini/</link>
		<comments>http://blog.4bits.es/mini-una-biblioteca-para-procesar-archivos-ini/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 19:17:35 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Proyectos]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=437</guid>
		<description><![CDATA[Hace ya bastante tiempo en el trabajo me tocó lidiar con un programa (en C) que debía procesar la configuración de un archivo INI, para quién no lo sepa es un archivo de texto con un formato similar a este: ;Archivo INI [sección] clave1=valor1 clave2=valor2 En estos casos lo mejor es no reinventar la rueda, [...]]]></description>
			<content:encoded><![CDATA[<p>Hace ya bastante tiempo en el trabajo me tocó lidiar con <strong>un programa (en C) que debía procesar la configuración de un archivo INI</strong>, para quién no lo sepa es un archivo de texto con un formato similar a este:</p>
<pre class="brush:text">;Archivo INI

[sección]
clave1=valor1
clave2=valor2</pre>
<p>En estos casos lo mejor es no reinventar la rueda, así que hice un par de búsquedas por internet, pero lo que encontré no me gustó, así que ni corto ni perezoso realicé mi propio <em>cutre-parser</em> que funcionaba bien para lo que quería, archivos INI creados a mano, pero no para todos los casos que podría tener un archivo INI.</p>
<p>Así que gracias a un poco de tiempo libre me he puesto las pilas un poco y he ido modificando aquel <em>cutre-parser</em> hasta algo más decente, aunque todavía le quiero dar un par de vueltas para dejarlo bien. De todos modos, el código que hay ahora mismo funciona bastante bien, así que he creado un <a href="http://github.com/franchukelly/mini">repositorio para mini en github</a> (por cierto, git mola mil), así no tenéis excusa para probarlo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/mini-una-biblioteca-para-procesar-archivos-ini/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Autotools</title>
		<link>http://blog.4bits.es/autotools/</link>
		<comments>http://blog.4bits.es/autotools/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 09:36:40 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=359</guid>
		<description><![CDATA[Si alguien sabe lo que son las autotools, seguramente haya sufrido para saber cómo funcionan. Hacía mucho tiempo que no me peleaba con ellas, hasta que hace unos días leí un pequeño manual sobre cómo configurar los diferentes archivos necesarios y me acordé de un pequeño manual que hice cuando me tocó pegarme con ellas, [...]]]></description>
			<content:encoded><![CDATA[<p>Si alguien sabe lo que son <strong>las <em>autotools</em>, seguramente haya sufrido para saber cómo funcionan.</strong> Hacía mucho tiempo que no me peleaba con ellas, hasta que hace unos días leí un pequeño manual sobre cómo configurar los diferentes archivos necesarios y me acordé de un pequeño manual que hice cuando me tocó pegarme con ellas, que voy a recuperar.</p>
<h3>¿Qué son las <em>autotools</em>?</h3>
<p>Las <em>autotools</em>, son programas que se usan para crear un paquete de código fuente que se pueda distribuir y compilar de una manera sencilla (<code>configure</code>, <code>make</code> y <code>make install</code>). Los programas que forman las <em>autotools</em> son los siguientes:</p>
<ul>
<li><code>aclocal</code></li>
<li><code>autoconf</code></li>
<li><code>automake</code></li>
</ul>
<p>Estos programas son la base para crear el paquete de código fuente, para ello se tendrán que generar unos archivos concretos.</p>
<h3>Estructura del código fuente a distribuir</h3>
<p>Las <em>autotools</em> se usan para generar el paquete «tar.gz» que contiene el código fuente del programa que se va a distribuir, normalmente estos paquetes siguen una estructura estándar. La estructura básica es:</p>
<ul>
<li><code>src</code>: Directorio del código fuente.</li>
<li><code>AUTHORS</code>: Indica los autores del programa.</li>
<li><code>ChangeLog</code>: Indica los cambios que se han ido produciendo.</li>
<li><code>COPYING</code>: Indica la licencia de distribución que tiene el programa. (Autogenerado)</li>
<li><code>INSTALL</code>: Explica cómo instalar el programa. (Autogenerado)</li>
<li><code>NEWS</code>: Indica las noticias relacionadas con el programa.</li>
<li><code>README</code>: Un pequeño documento en el que se describe el programa y se explican temas concretos de éste.</li>
<li><code>THANKS</code>: Indica los agradecimientos que tenga el autor/es.</li>
<li><code>TODO</code>: Indica una pequeña lista de cosas por hacer.</li>
</ul>
<p>De este modo, si se van a utilizar las <em>autotools</em> sería aconsejable seguir la estructura anterior, y crear todos los archivos menos los como «autogenerado» que, obviamente, se generarán automáticamente, aunque siempre se pueden crear a mano ya que puede que no se quiera tener el contenido autogenerado.</p>
<h3>El archivo «configure.ac»</h3>
<p>Sobre este archivo gira toda la generación del programa para su distribución. En él se escriben las macros para los diferentes programas que se ejecutarán: <code>aclocal</code>, <code>autoconf</code> y <code>automake</code>.</p>
<pre class="brush:text">AC_PREREQ(2.52)
AC_INIT([hola mundo], [0.1])
AM_INIT_AUTOMAKE([])

AC_PROG_CC
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT</pre>
<ul>
<li><strong>Programa aclocal:</strong> Sirve para generar el archivo «aclocal.m4». ¡Sólo se generará si en el archivo «configure.ac» hay macros de <code>automake</code>!</li>
<li><strong>Macros de autoconf:</strong> Empiezan por <code>AC_*</code>, y se buscan en el archivo «configure.ac» y en el «aclocal.m4» si existe. Sirven para la configuración correcta del programa.</li>
<ul>
<li><code>AC_PREREQ(versión)</code> indica la versión de <code>autoconf</code> necesaria.</li>
<li><code>AC_INIT([aplicación], [versión])</code> inicializa <code>autoconf</code>, recibe como parámetros el nombre del programa y su versión.</li>
<li><code>AC_PROG_CC</code> indica que realizará una compilación de código escrito en C.</li>
<li><code>AC_CONFIG_FILES([Makefile src/Makefile])</code> indica los archivos «Makefile» que se van a generar a partir de sus respectivos «Makefile.am».</li>
<li><code>AC_OUTPUT</code> indica los archivos que ﬁnalmente debe generar el script «conﬁgure».</li>
</ul>
<li><strong>Macros de automake:</strong> Empiezan por <code>AM_*</code>, y sirven para la generación de los diferentes «Makefile».</li>
<ul>
<li><code>AM_INIT_AUTOMAKE([])</code> inicializa <code>automake</code>, se le puede pasar un parámetro que la verdad no sé lo que indica, para mi ejemplo no hace falta pasárselo.</li>
</ul>
</ul>
<p><strong>Aviso:</strong> Las macros no pueden llevar un espacio entre su nombre y el paréntesis de inicio.</p>
<h3>Los archivos «Makefile.am»</h3>
<p>Los archivos «Makefile.am» contienen las reglas para generar los archivos «Makefile» correspondientes a los directorios dónde se encuentran, por lo que habrá un archivo por directorio en el que se tenga que realizar alguna operación con <code>make</code>.</p>
<p>De este modo, siempre se debe tener un archivo «Makefile.am» en el directorio raíz del proyecto, este archivo contendrá algo similar a lo siguiente:</p>
<pre class="brush:text">SUBDIRS = src
EXTRA_DIST = AUTHORS ChangeLog NEWS README THANKS TODO</pre>
<ul>
<li><strong>SUBDIRS</strong> enumera los directorios que contienen otros archivos «Makefile.am».</li>
<li><strong>EXTRA_DIST</strong> enumera los distintos archivos que deberá tener el paquete, para distribuir el código fuente que se generará.</li>
</ul>
<p>En este caso el directorio «src» es dónde, supuestamente, deberá estar el código fuente de nuestra aplicación y tendrá un archivo «Makefile.am», que indicará las reglas para compilar nuestro código fuente correctamente.</p>
<p>El archivo «Makefile.am» tendrá el siguiente contenido:</p>
<pre class="brush:text">bin_PROGRAMS = hola−mundo
hola_mundo_SOURCES = hola−mundo.c</pre>
<ul>
<li><strong>bin_PROGRAMS</strong> indica el nombre del ejecutable final.</li>
<li><strong>hola_mundo_SOURCES</strong> indica los archivos con el código fuente de la aplicación.</li>
<li>Si se necesitarán bibliotecas se debería añadir <strong>hola_mundo_LDADD</strong> con las macros necesarias para dichas bibliotecas en el archivo «configure.ac».</li>
</ul>
<p><strong>Nota:</strong> Para generar una biblioteca, se debería usar <code>libexec_PROGRAMS</code> en lugar de <code>bin_PROGRAMS</code>.</p>
<h3>Generación del script «configure»</h3>
<p>Una vez creados los archivos necesarios, se deben realizar los siguientes pasos:</p>
<ol>
<li>Generación:
<pre class="brush:text">$ aclocal
$ autoconf
$ automake --add-missing</pre>
</li>
<li>Compilación y ejecución del programa:
<pre class="brush:text">$ ./configure
$ make
$ src/hola−mundo</pre>
</li>
<li>Distribución del programa:
<pre class="brush:text">$ make distcheck</pre>
</li>
</ol>
<p>Para ampliar un poco más <a href="http://smalltalk.gnu.org/blog/bonzinip/all-you-should-really-know-about-autoconf-and-automake">All you should really know about Autoconf and Automake</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/autotools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows System Programming</title>
		<link>http://blog.4bits.es/windows-system-programming/</link>
		<comments>http://blog.4bits.es/windows-system-programming/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 14:45:38 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Libros]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=233</guid>
		<description><![CDATA[Windows System Programming es un libro de introducción a la programación sobre Windows (Win32, aunque hay una breve introducción a Win64), con el lenguaje C. He de decir que este libro no me ha sorprendido mucho, ya que en cuanto llevas algo de tiempo programando sobre Win32 y visitando la MSDN a menudo, te acabas [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.4bits.es/wp-content/uploads/2009/06/wsp_3.gif" alt="Windows System Programming" class="alignleft" width="150" height="188" /><strong>Windows System Programming</strong> es un libro de introducción a la programación sobre Windows (<a href="http://en.wikipedia.org/wiki/Windows_API">Win32</a>, aunque hay una breve introducción a Win64), con el lenguaje C.</p>
<p>He de decir que este libro no me ha sorprendido mucho, ya que en cuanto llevas algo de tiempo programando sobre Win32 y visitando la <a href="http://www.msdn.com">MSDN</a> a menudo, te acabas conociendo las partes más utilizadas. Además, <strong>este libro es bastante antiguo (del 2004).</strong></p>
<p>En general, no me convence la forma de explicar los temas por parte del autor, <strong>casi todos los capítulos se limita a copiar las diferentes funciones</strong> que se utilizan para hacer lo que sea, y a explicar cada uno de sus parámetros. Por lo que el libro se transforma en una especie de resumen de la MSDN.</p>
<p>De todo el contenido <strong>del libro me quedaría con los capítulos sobre los servicios de Windows y las estructuras de seguridad</strong> (SIDs, ACLs, ACEs) de Windows.</p>
<p>Aún así, puede servir como punto de partida para empezar a programar sobre Windows utilizando Win32, si no fuera por las pegas que he comentado.</p>
<p><strong>Recomendación:</strong> Baja.<br />
<strong>Nivel:</strong> Medio.<br />
<strong>Idioma:</strong> Inglés.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/windows-system-programming/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Manejar las señales de control de la consola de Windows</title>
		<link>http://blog.4bits.es/manejar-las-senales-de-control-de-la-consola-de-windows/</link>
		<comments>http://blog.4bits.es/manejar-las-senales-de-control-de-la-consola-de-windows/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 08:45:09 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=191</guid>
		<description><![CDATA[En Windows existen cinco señales de la consola que se emiten cuando se producen varios eventos, todos relacionados con el fin de la aplicación (Ctrl+C o Ctrl+Break), con el cierre de la consola (más llanamente, es el cierre de la ventana del cmd.exe) o con el fin de la sesión en Windows (el cierre de [...]]]></description>
			<content:encoded><![CDATA[<p>En Windows existen cinco señales de la consola que se emiten cuando se producen varios eventos, todos relacionados con el fin de la aplicación (Ctrl+C o Ctrl+Break), con el cierre de la consola (más llanamente, es el cierre de la ventana del cmd.exe) o con el fin de la sesión en Windows (el cierre de una sesión de usuario o el apagado del sistema).</p>
<p>Windows emite estas señales a las aplicaciones correspondientes para que puedan manejarlas y terminar de una forma adecuada, por ejemplo: realizando las operaciones necesarias para no dejar archivos en algún estado catastrófico perdiendo la información de estos.</p>
<h3>Manejando las señales</h3>
<p>Para manejar estas señales las aplicaciones disponen de una lista de manejadores, en la que en principio sólo hay una función que termina la ejecución del proceso. Para añadir/borrar un manejador a la lista se dispone de la función <a href="http://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx">SetConsoleCtrlHandler</a>:</p>
<pre>BOOL WINAPI SetConsoleCtrlHandler (PHANDLER_ROUTINE HandlerRoutine, BOOL Add);</pre>
<p>Donde los parámetros son:</p>
<ul>
<li><strong>HandlerRoutine:</strong> Es un puntero a la función que manejará las señales recibidas. Tendrá la forma:
<pre>BOOL WINAPI CtrlHandler (DWORD CtrlType)</pre>
</li>
<li><strong>Add:</strong> Si su valor es TRUE indica que la función se añadirá a la lista de manejadores de las señales, en cambio si es FALSE indica que la función se borrará de la lista de manejadores.</li>
</ul>
<h3>La función del manejador</h3>
<p>Como se ha mencionado antes, <a href="http://msdn.microsoft.com/en-us/library/ms683242(VS.85).aspx">la función del manejador</a> tiene la forma:</p>
<pre>BOOL CtrlHandler (DWORD CtrlType);</pre>
<p>La función del manejador deberá tratar las señales que crea conveniente, utilizando el parámetro <strong>CtrlType</strong> que recibirá uno de los siguientes valores:</p>
<ul>
<li>CTRL_C_EVENT: Señal de Ctrl+C.</li>
<li>CTRL_BREAK_EVENT: Señal de Ctrl+Break.</li>
<li>CTRL_CLOSE_EVENT: Señal del cierre de la ventana de la consola.</li>
<li>CTRL_LOGOFF_EVENT: Señal del cierre de la sesión.</li>
<li>CTRL_SHUTDOWN_EVENT: Señal del apagado del sistema</li>
</ul>
<p>Este manejador devolverá TRUE cuando haya tratado la señal, y FALSE cuando no la haya tratado, de modo que pasará a ejecutar el siguiente manejador.</p>
<h3>Ejemplo</h3>
<p>Como todo se entiende mejor con un ejemplo, aquí os dejo <a href="http://msdn.microsoft.com/en-us/library/ms685049(VS.85).aspx">el ejemplo de la MSDN sobre registrar un manejador de señales de control de la consola</a>:</p>
<pre class="brush:c">#include &lt;windows.h&gt;
#include &lt;stdio.h&gt;

BOOL WINAPI CtrlHandler (DWORD CtrlType) {

    switch (CtrlType) {

        // Handle the CTRL-C signal.
        case CTRL_C_EVENT:
            printf ("Ctrl-C event\n\n");
            Beep (750, 300);
            return TRUE;

        // CTRL-CLOSE: confirm that the user wants to exit.
        case CTRL_CLOSE_EVENT:
            printf ("Ctrl-Close event\n\n");
            Beep (600, 200);
            return TRUE;

        // Pass other signals to the next handler.
        case CTRL_BREAK_EVENT:
            printf ("Ctrl-Break event\n\n");
            Beep (900, 200);
            return FALSE;

        case CTRL_LOGOFF_EVENT:
            printf ("Ctrl-Logoff event\n\n");
            Beep (1000, 200);
            return FALSE;

        case CTRL_SHUTDOWN_EVENT:
            printf ("Ctrl-Shutdown event\n\n");
            Beep (750, 500);
            return FALSE;

        default:
            return FALSE;
    }
}

int main (int argc, char *argv[]) {

    BOOL added;

    added = SetConsoleCtrlHandler ((PHANDLER_ROUTINE) CtrlHandler,
                                   TRUE);
    if (added) {
        printf ("\nThe Control Handler is installed.\n");
        printf ("\n -- Now try pressing Ctrl+C or Ctrl+Break, or");
        printf ("\n    try logging off or closing the console...\n");
        printf ("\n(...waiting in a loop for events...)\n\n");

        while (1) {
            Sleep (500);
        }

    } else
        printf ("\nERROR: Could not set control handler");

    return 0;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/manejar-las-senales-de-control-de-la-consola-de-windows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Texto coloreado en la consola de Linux</title>
		<link>http://blog.4bits.es/texto-coloreado-consola-linux/</link>
		<comments>http://blog.4bits.es/texto-coloreado-consola-linux/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 17:07:15 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Recursos]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=127</guid>
		<description><![CDATA[Si alguna vez habéis tenido que programar algo para funcionar sobre la consola de Linux, a lo mejor os habría gustado poder colorear la salida, como hacen la mayoría de los programas de la consola de Linux. Pues si vuestra consola admite colores ANSI (casi todas lo hacen, incluso la de Windows), lo tenéis muy [...]]]></description>
			<content:encoded><![CDATA[<p>Si alguna vez habéis tenido que programar algo para funcionar sobre la consola de Linux, a lo mejor os habría gustado poder colorear la salida, como hacen la mayoría de los programas de la consola de Linux.</p>
<p>Pues si vuestra consola admite colores ANSI (casi todas lo hacen, incluso la de Windows), lo tenéis muy fácil ya que mediante unas cadenas de escape se pueden cambiar los colores. Estas cadenas siguen un patrón del tipo:</p>
<pre>&lt;ESC&gt;[{attr1};...;{attrn}m</pre>
<p>Donde <strong>attrX</strong> es un código numérico que determina una característica del texto (como subrayado), el color del texto y el color del fondo de éste. Estos código están definidos y se pueden consultar en <a href="http://www.termsys.demon.co.uk/vtansi.htm">esta web</a> que contiene las cadenas de escape ANSI.</p>
<p>De este modo, <strong>si se quiere cambiar el color del texto</strong>, por ejemplo <strong>en un programa en C</strong>, se haría lo siguiente:</p>
<pre class="brush:c">printf ("\e[32m Soy de color verde\n");
printf ("\e[0m Vuelvo a ser del color normal.\n");</pre>
<p>Lo normal es que estas cadenas se guarden en algún tipo de constantes, para luego usarlas y no tener que escribir la cadena de escape cada vez que queramos cambiar el color.</p>
<p>(Sacado de <a href="http://voiser.es/blog/?p=137">zeros and ones</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/texto-coloreado-consola-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Aprendiendo GTK+: Destripando los widgets</title>
		<link>http://blog.4bits.es/aprendiendo-gtk-destripando-widgets/</link>
		<comments>http://blog.4bits.es/aprendiendo-gtk-destripando-widgets/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 07:00:49 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GTK]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=103</guid>
		<description><![CDATA[Aunque comencé explicándoos como funcionan las ventanas y los contenedores de GTK+ creo que lo mejor habría sido explicar primero qué son y cómo funcionan los widgets de GTK+. Así que aquí viene una explicación sobre los widgets. La clase GtkWidget Es la clase básica de la que parte cualquier otro widget de GTK+, esta [...]]]></description>
			<content:encoded><![CDATA[<p>Aunque comencé explicándoos como funcionan las <a href="http://blog.4bits.es/aprendiendo-gtk-ventanas/">ventanas</a> y los <a href="http://blog.4bits.es/aprendiendo-gtk-contenedores/">contenedores</a> de GTK+ creo que lo mejor habría sido explicar primero <strong>qué son y cómo funcionan los <em>widgets</em> de GTK+</strong>. Así que aquí viene una explicación sobre los <em>widgets</em>.</p>
<h3>La clase GtkWidget</h3>
<p>Es la clase básica de la que parte cualquier otro <em>widget</em> de GTK+, esta clase en sí misma no hace nada específico (por ejemplo: un cuadro de texto, un botón, &#8230;) para ello existen clases específicas, como las ventanas o los contenedores. Estas clases más específicas heredan de la clase <strong><a href="http://library.gnome.org/devel/gtk/stable/GtkWidget.html">GtkWidget</a></strong> las funciones, atributos y señales básicas que les hacen ser clases válidas para poder usarse en GTK+.</p>
<h3>Partes esenciales de un widget</h3>
<p>Como cualquier clase de cualquier lenguaje de programación orientado a objetos, la clase de un <em>widget</em> se divide en:</p>
<ul>
<li><strong>Funciones:</strong> Son las funciones que permiten trabajar con dicha clase. Aquí las llamo funciones porque estamos trabajando sobre C, si fuera sobre cualquier lenguaje de programación orientado a objetos las llamaría métodos.</li>
<li><strong>Atributos (o propiedades):</strong> Son variables asociadas a la clase que identifican propiedades de ésta, por ejemplo: el color, la altura, &#8230;</li>
<li><strong>Señales:</strong> Muchos lenguajes de programación orientada a objetos no usan señales, pero en GTK+ son necesarias para controlar los eventos.<br />
Las señales identifican el evento que se ha producido, y se deben asociar a alguna función para que GTK+ al interceptar la señal ejecute dicha función, por ejemplo: al pulsar un botón que se escriba un mensaje en un cuadro de texto, la señal sería la pulsación del botón y la función asociada a ella la escritura del mensaje en el cuadro de texto.</li>
</ul>
<p>De este modo, en <a href="http://library.gnome.org/devel/gtk/stable/">la documentación de la API de GTK+</a>, se puede observar que cada <em>widget</em> se descompone en estas partes para que sepamos claramente qué se puede hacer y/o qué tareas realiza dicho <em>widget</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/aprendiendo-gtk-destripando-widgets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aprendiendo GTK+: Ventanas</title>
		<link>http://blog.4bits.es/aprendiendo-gtk-ventanas/</link>
		<comments>http://blog.4bits.es/aprendiendo-gtk-ventanas/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 16:43:50 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[GTK]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=93</guid>
		<description><![CDATA[He aquí otro capítulo de esta serie que deje abandonada hace tiempo, ya que cuando uno empieza a trabajar le quedan pocas ganas al llegar a casa de ponerse a pensar, pero resulta que desde hace días me han venido las ganas de revitalizar este blog. Las ventanas Las ventanas son los widgets raíces, ya [...]]]></description>
			<content:encoded><![CDATA[<p>He aquí otro capítulo de esta serie que deje abandonada hace tiempo, ya que cuando uno empieza a trabajar le quedan pocas ganas al llegar a casa de ponerse a pensar, pero resulta que desde hace días me han venido las ganas de revitalizar este blog.</p>
<h3>Las ventanas</h3>
<p>Las ventanas son los widgets raíces, ya que sin ellas no podría haber aplicación. Hereda las propiedades de GtkContainer, por lo que puede contener a otro widget <em>(¡cuidado! sólo a uno)</em>, por lo que lo normal es que dentro de una ventana se introduzca un GtkBox de algún tipo, en el que se coloquen el resto de widgets de la aplicación.</p>
<p>Como veis en el título digo <em>ventanas</em>, y es que <a href="http://library.gnome.org/devel/gtk/stable/WindowWidgets.html">hay varios tipos de ventanas</a>:</p>
<ul>
<li><a href="http://library.gnome.org/devel/gtk/stable/GtkDialog.html">GtkDialog</a>: Crea una ventana emergente. Dentro de este tipo de ventanas existen varios tipos predefinidos como el dialogo de &#8220;Acerca de&#8221;, el de elección de archivo, el de elección de color, &#8230;</li>
<li><a href="http://library.gnome.org/devel/gtk/stable/GtkInvisible.html">GtkInvisible</a>: Crea una ventana invisible.</li>
<li><a href="http://library.gnome.org/devel/gtk/stable/GtkMessageDialog.html">GtkMessageDialog</a>: Crea una ventana con un mensaje personalizado, es uno de los tipos predefinidos del GtkDialog. Son las ventanas que muestran mensajes de error, advertencia, &#8230;</li>
<li><a href="http://library.gnome.org/devel/gtk/stable/GtkWindow.html">GtkWindow</a>: Crea una ventana normal y corriente. Será el widget que se use como base para cualquier aplicación.</li>
<li><a href="http://library.gnome.org/devel/gtk/stable/GtkAssistant.html">GtkAssistant</a>: Crea un asistente para guiar al usuario en varios pasos.</li>
</ul>
<p>Como he dicho, de todos estos tipos el más importante es GtkWindow, que es la ventana normal y corriente que tiene cualquier aplicación.</p>
<p>Como cualquier widget de GTK, GtkWindow es muy fácil de manejar con echar un ojo a la documentación de la API se aprende rápido como funciona todo. A continuación os pongo un trozo de código en el que creo una ventana vacía:</p>
<pre class="brush:c">#include &lt;gtk/gtk.h&gt;

int main (int argc, char *argv[]) {

    GtkWindow *window;

    gtk_init (&#038;argc, &#038;argv);

    window = (GtkWindow *) gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (window, "Soy una ventana");

    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (gtk_main_quit), NULL);

    gtk_widget_show_all (GTK_WIDGET (window));
    gtk_main ();

    return 0;
}</pre>
<p>Este código muestra una ventana con el título <em>Soy una ventana</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/aprendiendo-gtk-ventanas/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Generador de contraseñas</title>
		<link>http://blog.4bits.es/generador-de-contrasenas/</link>
		<comments>http://blog.4bits.es/generador-de-contrasenas/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 18:37:58 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Seguridad]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=72</guid>
		<description><![CDATA[Llevo ya tiempo pensando en cambiar mis contraseñas, tengo unas cuantas para diferentes cosas (como debe ser), pero se me están quedando cortas y ya uso la misma para algunas cosas (como no debe ser), así que quiero renovarlas. Por este motivo, se me ocurrió hacer un pequeño programa (en C) que genera contraseñas aleatorias [...]]]></description>
			<content:encoded><![CDATA[<p>Llevo ya tiempo pensando en cambiar mis contraseñas, tengo unas cuantas para diferentes cosas (como debe ser), pero se me están quedando cortas y ya uso la misma para algunas cosas (como no debe ser), así que quiero renovarlas.</p>
<p>Por este motivo, se me ocurrió hacer <strong>un pequeño programa (en C) que genera contraseñas aleatorias (llamado passwdgen)</strong>, con una serie de opciones:</p>
<ul>
<li>En base al conjunto alfanumérico (alfabeto en mayúsculas, minúsculas y/o números).</li>
<li>Longitud mínima y/o máxima personalizable, si se le da una mínima y otra máxima se escogerá una longitud aleatoria entre los valores dados. (La longitud predeterminada es de ocho caracteres)</li>
</ul>
<p>De este modo, <strong>se genera aleatoriamente una cadena de caracteres en base al conjunto de caracteres y la longitud que queramos.</strong> Lo he subido a Google Code para que todos podáis hacer uso de él y/o si queréis trastear con <a href="http://code.google.com/p/passwdgen/source/browse/#svn/trunk">el código</a>, está licenciado bajo GPL 2.</p>
<p>Si estáis interesados, visitad la <a href="http://code.google.com/p/passwdgen/">web de passwdgen</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/generador-de-contrasenas/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Tuberías en Linux</title>
		<link>http://blog.4bits.es/tuberias-linux/</link>
		<comments>http://blog.4bits.es/tuberias-linux/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 18:26:47 +0000</pubDate>
		<dc:creator>Fran</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.4bits.es/?p=62</guid>
		<description><![CDATA[Hace unos días expliqué cómo redirigir la salida de un proceso que ejecutemos desde nuestro programa en Windows, hoy voy a explicar cómo hacerlo en Linux (algo que todos deberías de saber ya). #include &#60;stdio.h&#62; #include &#60;unistd.h&#62; #include &#60;stdlib.h&#62; #include &#60;string.h&#62; /* Proceso hijo */ void do_child (int data_pipe[]) { /* Cerramos la parte de [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días expliqué <a href="http://blog.4bits.es/tuberias-windows/">cómo redirigir la salida de un proceso que ejecutemos desde nuestro programa en Windows</a>, hoy voy a explicar cómo hacerlo en Linux (algo que todos deberías de saber ya).</p>
<pre class="brush:c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

/* Proceso hijo */
void
do_child (int data_pipe[])
{
    /* Cerramos la parte de la tubería que no usamos (lectura) */
    close (data_pipe[0]);

    /* Tubería de escritura a salida estándar */
    dup2 (data_pipe[1], STDOUT_FILENO);

    /* Ejecutamos el proceso que queramos (p. ej.: ls) */
    execvp ("ls", NULL);

    perror ("execvp");
}

/* Proceso padre */
void
do_parent (int data_pipe[])
{
    char salida[200];
    int nread;

    /* Cerramos la parte de escritura */
    close (data_pipe[1]);

    /* Leemos la salida */
    nread = read (data_pipe[0], salida, 200);
    while (nread > 0) {
        printf ("%s", salida);
        nread = read (data_pipe[0], salida, 200);
    }

    close (data_pipe[0]);
}

int
main (int argc, char* argv[])
{
    int data_pipe[2];
    int pid;
    int rc;       

    rc = pipe (data_pipe);
    if (rc == -1) {
        perror ("pipe");
        exit (1);
    }

    pid = fork ();
    switch (pid) {
        case -1:
            perror ("fork");
            break;

        /* Proceso hijo */
        case 0:
            do_child (data_pipe);
            break;

        /* Proceso padre */
        default:
            do_parent (data_pipe);
            break;
    }

    return 0;
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.4bits.es/tuberias-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
