Día de buenas noticias para el software libre

Jueves, 4 de Febrero de 2010 admin Sin comentarios

Hoy parece que es un  buen día, me he levantado con dos buenas noticias.

aplicaciones-symbianSymbian ya es Software Libre, una muy buena noticia, ya podemos investigar cómo está hecho y desde luego quieren que la comunidad intervenga en hacer mejoras. Podemos ver más información acerca de esto: PC World, Symbian Developer Community.

La segunda gran noticia de hoy es que la Administración española, está obligada a comunicarse entre administraciones y con los ciudadanos utilizando estándares abiertos. Lo leí aquí esta mañana, y tal y como dicen, ahora mismo la página del Defensor del pueblo, si queremos utilizar nuestro certificado digital necesitamos Internet Explorer, mientras cada vez más gente rechaza el uso de este para cosas serias; puede que ese antiguo sistema tenga los días contados. Por otra parte, como ciudadanos deberíamos ver más a menudo cómo se comunican con nosotros con documentos OpenDocument, y deberían aceptarnos a nosotros estos documentos. Toda esta parrafada (es un PDF del BOE) es muy bonita, deberíamos esperar antes de cantar victoria a ver la implementación de todo esto, tal vez luego encontremos desarrollos hechos sin mucha gana con respecto a las webs y firmas digitales, y documentos OpenDocument (muy bien) que se note a la legua que están hechos con MS. Word y luego copiados y pegados (mal). De todas formas, enhorabuena, es un buen primer paso.

Una idea acerca de la web de RENFE

Miércoles, 3 de Febrero de 2010 admin Sin comentarios

Todos los que hemos tenido que utilizar la web de Renfe alguna vez, hemos sufrido sus daños y seguimos con sus secuelas.

Encontraréis un nuevo rediseño de la web aquí.

Porque encima de que algunas empresas quieren vender un producto o servicio, y nosotros queremos comprarlo, no se preocupan de mejorar sus webs para hacerlo posible. Podríamos tener la posibilidad de contratar los servicios con otra empresa que tuviera una web mejor, pero como ocurre en este y otros muchos casos suelen ser las empresas únicas empresas que lo ofrecen.

Es el caso de ALSA o grupo Avanza, con algunos trayectos, canal cliente Movistar sólo funciona en IE (y a veces); cuyas webs a veces dan más de un calentamientos de cabeza al usuario; y muchas tiendas online…

Categories: Interneteando Tags: , ,

Web hosting: Malas experiencias con Honesting

Sábado, 30 de Enero de 2010 admin Sin comentarios

hostingDe esto hace ya algún tiempo (Enero-Febrero de 2006), pero aún sigo dolido.

Tenía un proyecto web, que estaba tomando algo de forma, tenía un número considerable de visitas, y estaba muy contento con él, me costó mucho esfuerzo y aunque el hosting no era caro, era lo que me podía permitir. Bien, empecé con esta empresa un tiempo antes y todo fue bien, hay que reconocer que llegué a mandar tickets de soporte a las 4:00 AM y me respondían enseguida; pero en verano de 2005, un exploit de Joomla se cargó todas las webs del servidor (curioso, una seguridad tremenda), y no restauraron mi copia de seguridad porque tenían webs más prioritarias (bueno, pasa)… y a finales de 2005, empecé a notar cómo no se leían los tickets que enviaba, es decir, cuando tenía algún problema, yo detallaba las pruebas que ya había hecho, y me empezaban a repetir lo que había puesto, es más en las respuestas no tenían en cuenta lo de los mensajes anteriores, por lo que al final debía resumir en cada mensaje todo lo hablado anteriormente, y cualquier problema se convertía en un calvario de varios días (al menos tardaban relativamente poco en contestar).

Pero un día me encuentro con que no puedo ver mi correo (y ya que, aunque tenían teléfono nunca lo cogían), accedo al panel de control, envío un ticket, y me habían cortado el servicio (la web tampoco funcionaba) por enviar SPAM… luego me dicen que excedí la transferencia de correo (cosa improbable porque en las estadísticas de correo saliente todo era normal), la reactivan y a los dos días me cortan de nuevo el servicio, y me cuesta 5 tickets que me lo rehabiliten, pero a la tercera vez que me lo quitan no me dicen nada, tardan todo el día en contestar para decirme que he excedido el uso de CPU y que… mi página estaba mal diseñada (a ellos no les importaba cómo estuviera diseñada mi web); por lo de la CPU es relativo, es normal que si intentan meter a 2000 usuarios en la misma máquina, el servicio no vaya todo lo bien que debería, llevaba 2 años con la web con ellos sin problemas. Pero lo más curioso es que todos los problemas empezaron 15 días después de pagar la cuota anual…

Después de muchos tickets (que borraron antes de que pudiera copiarlos) conseguí que me subieran una copia de seguridad a la red para poder descargarla, eso sí, durante el tiempo que estuvo la copia de seguridad colgada, no tuvo ningún sistema de seguridad (ni contraseña para descargar ni nada), es decir, dejaron mis contraseñas, mis mails, información privada mía y de casi 2000 usuarios de la web descargable por todo el mundo. Tras haberme quejado mil veces por toda la red, aquí va la 1001, no es una empresa seria y menos aún honesta. Y además, no soy el único que lo ha pasado mal con esta gente. Aunque, según veo comentarios, todavía sigue haciendo de las suyas.

Fui a la oficina del consumidor, y me dijeron que la única solución era poner una denuncia porque la oficina era ilocalizable, le mandaron una carta oficial y llegó de vuelta, y a los teléfonos que les dí no les cogieron ni una vez.

Una cosa más, el encargado de esta pseudoempresa, se crea mil perfiles en foros, Ciao, y mil sitios, pero si os paráis a leer tranquilamente, esos clones no aportan mucha información y lo único que aportan es repetido, no viene a cuento y da la casualidad de que sólo entran para hacer ruido.

Foto original de John Seb.

Categories: General Tags: , ,

Crea tu avatar en 3D

Viernes, 29 de Enero de 2010 admin 2 comentarios

Nacen cientos de servicios web al mes, pero hoy, vía rm -rf /, he descubierto uno que me ha sorprendido!

En principio, parece la típica página para crear avatares, pero con un detalle añadido, son en 3D, queda bien, queda gracioso, pero es que además están animados (son animaciones de unos 5 segundos, no es mucho, y a lo mejor cuando las veas 5 veces ya cansan, pero mira)…

Pero al entrar en la página, hay una opción que me agrada: Your own photo; y sí, te permite subir tu foto y crearte un carácter en 3D, como tú, no es instantáneo, pero en unos 10 minutos (siguiendo unas instrucciones) tienes un muñecajo en 3D personalizado… y todo gratis (no sé qué tratamiento harán con la imagen, pero para poner una foto en Facebook está muy bien).

La web es: www.avatara.com

Yo tuve que subir la foto 3 veces porque me falló, supongo que será un poco la saturación del servidor, ya que crear los avatares 3D no tiene que ser una tarea muy ligera, y si además hay muchas peticiones de lo mismo, llegará un momento que no se pueden atender todas.

Os dejo aquí el mío:

yo_wink

Identificar si estamos en el servidor local o no

Lunes, 25 de Enero de 2010 admin Sin comentarios

A veces es interesante saber en qué servidor estamos, si en nuestro servidor local para hacer pruebas, o en el remoto (y será la web definitiva); puede que porque las claves de mi servidor MySQL local son diferentes, o porque en local activamos automáticamente el modo de depuración, o símplemente porque en nuestro servidor local tenemos todos nuestros proyectos como http://localhost/proyecto1/ y en el servidor se ejecutarán como http://www.proyecto1.com/.

Para ello nos vale esta línea que podemos incluir en nuestra biblioteca de funciones personal en PHP:

1
$serv_local = (file_exists($_SERVER['DOCUMENT_ROOT']."/serv_local"));

Ahora en nuestro servidor local (valga la redundancia en todo el post) hacemos un touch en nuestro DOCUMENT_ROOT (por ejemplo /home/www/public_http/):

1
2
$ cd /home/www/public_http
$ touch serv_local

Con esto siempre que ejecutemos nuestros scripts buscaremos el fichero serv_local, si se encuentra, estamos seguros de que estamos en nuestro ordenador, si no, estamos en el servidor remoto.

Categories: PHP Tags: , ,

Caché+Compresión+Palabras clave en ficheros CSS y JS

Viernes, 22 de Enero de 2010 admin Sin comentarios

Cuando nos aventuramos en un proyecto web con más o menos visitas, queremos que sea lo más rápido para el usuario y para ello enviar la menor cantidad de información (si nuestro hosting nos cobra además por transferencia también ganamos por esto), para ello podemos comprimir la información (y ya lo soportan la mayoría de los navegadores).
Aunque tenemos que tener en cuenta que si comprimimos información (la compresión es un proceso algo pesado), estamos gastando recursos de CPU que, si lo pensamos, estar comprimiendo la misma información a cada petición que nos hagan de un fichero Javascript es tontería; por tanto, una vez que lo comprimamos, lo almacenamos en disco, que este tipo de información no ocupa tanto.
Por otra parte, si eres de los que realizan una plantilla más o menos completa y la publica con pequeñas modificaciones en diferentes webs, o incluso estar preparados para que un cliente nos cambie la gama de colores y no echarnos las manos a la cabeza; o por ejemplo cuando tenemos que tener en cuenta el mismo color tanto en el código CSS como en el Javascript, podemos escribir ciertas palabras clave dentro del fichero CSS y Javascript que nuestro script PHP traducirá antes de enviar la información al usuario final.

Para ello, y para poco más es el siguiente script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?
/* tcjs.php versión 0.05 Copyright 2010 Gaspar Fernández*/

/* Inclusión de keywords y compresión de archivos JS y CSS */

/* El código fuente se entrega tal cual, sin garantía para ser */
/* estudiado y utilizado en cualquier entorno libre y no libre. */
/* Eso si, agradecería que me comunicárais si lo usáis en un proyecto */
/* mandando un mail a blakeyed@totaki.com; sólo para saber que esto  */
/* se está usando en algún lugar del mundo :) */

/* Configuración del script */

/* $basepath normalmente es la ruta donde se encuentra el script. Es la ruta base
absoluta a partir de la cual se encuentran todos los archivos. Esta ruta será padre
de la ruta donde se encuentre el fichero CSS o JS que llamaremos. */

$basepath = '/home/gaspy/proyectos/www/poesiabinaria/tests/';
/* $httppath es la URL base de nuestra web o sección, normalmente será la dirección con la que
abriremos el directorio web correspondiente a $basepath. */

$httppath = 'http://localhost/poesiabinaria/tests/';
/* $cachedir es el directorio donde se encontrarán los cachés de los ficheros JS y CSS */
$cachedir = $basepath.'var/gzcache/';
/* $excluded_files es un archivo de texto donde se encuentran (uno por línea) todos los ficheros
que no pasarán por el procesador. Sólo serán comprimidos y guardados en caché. */

$excluded_files = $basepath.'var/excluded';
/* $definiciones_file es un archivo php que incluiremos cargando las definiciones necesarias para
completar el contenido de los CSS y JS. Puede haber un fichero de definiciones tanto raiz como
en el directorio donde se encuentra el CSS o JS a procesar.*/

$definiciones_file = 'lib/tcjc_defs.php';
/* FIN de Configuración del script */

function gf_getgz_cachefile($file)
{
/* Obtenemos un nombre de fichero único para los archivos de cache */
global $cachedir;
$getstr = $file.sizeof($file).filemtime($file);
$hash = base_convert(md5($getstr),16,36); /* Hash en base36 */

return $cachedir.$hash;
}

function add_ending_slash($path)
{
/* Añade una barra al final de la ruta del directorio */
$sep = (PHP_OS == 'Windows')? '\':'/';
$path .= (substr($path,-1) == $sep)? '':$sep;
return $path;
}

function genera_y_cachea($file, $cachefile)
{
/* Genera el cache, sustituyendo las definiciones */
global $basepath, $definiciones_file, $httppath;

$definiciones = array ('%%http_path%%' => $httppath);
/* Si tenemos un archivo auxiliar para incluir definiciones */
if (file_exists($basepath.$definiciones_file))
require_once($basepath.$definiciones_file);

$local_defs = add_ending_slash(dirname($file)).$definiciones_file;

if (file_exists($local_defs))
require_once($local_defs);

$triggers = array_keys($definiciones);
$reemplaz = array_values($definiciones);
$contenidos = file_get_contents($file);
$contenidos = str_replace($triggers, $reemplaz, $contenidos);
file_put_contents($cachefile, $contenidos);
$gz = gzopen($cachefile.".gz","wb5");
gzwrite($gz, $contenidos);
gzclose($gz);
}

function comprime($file, $cachefile)
{
/* Símplemente comprime el archivo */
$contenidos = file_get_contents($file);

file_put_contents($cachefile, $contenidos); /* Hacemos un backup también */
$gz = fopen($cachefile.".gz","wb");
fwrite($gz, gzencode($contenidos));
fclose($gz);
}

function interpretar($file)
{
/* Mira el archivo de excluidos y si no debo interpretarlo, devuelve false */
global $excluded_files;
if (file_exists($excluded_files))
{
$excl = file ($excluded_files);
return (!in_array($file, $excl)); /* Si la encontramos, devolvemos FALSE */
}
return true;
}

$type = (isset($_GET['type']))?$_GET['type']:false;
$file = (isset($_GET['file']))?$_GET['file']:false;

// Nos aseguramos de que las dos esté especificadas
if (($type) &amp;&amp; ($file))
{

/* Establecemos las cabeceras http necesarias */
switch ($type)
{
case 'css': header("Content-type: text/css; charset=utf-8"); break;
case 'js' : header("Content-type: text/javascript; charset=utf-8"); break;
}
header("Cache-Control: must-revalidate");

if (file_exists($basepath.$file))
{
$origftm = filemtime($basepath.$file);
$cachefile = gf_getgz_cachefile($basepath.$file); /* Genera un nombre de archivo de caché único */

@$destftm = filemtime($cachefile); /* No daremos error si no existe el archivo */

if ($origftm>$destftm)
{
/* Si el fichero original es más nuevo que su caché, lo procesamos todo de nuevo */
if (interpretar($file))
genera_y_cachea($basepath.$file, $cachefile);
else
comprime ($basepath.$file, $cachefile);
}

if ( (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) &amp;&amp; (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')))
{
header("Content-Encoding: gzip");
header("Content-Length: ".filesize($cachefile.".gz"));
readfile ($cachefile.".gz"); /* Si el navegador permite contenidos gzipeados... */
}
else
readfile ($cachefile);
}
/* else ERROR no existe el fichero CSS o JS */
}
/* else ERROR, no se ha especificado tipo de fichero o el fichero */
?>

También puedes descargarlo directamente: aquí: tcjs.php.gz (2.2Kb)
Lo que pretendo es que con este script sólo tengamos que copiar el archivo, definir un par de cosas y funcionar, y que sea totalmente transparente, tanto que nos olvidemos de que lo estamos usando.

Para instalarlo, podemos copiarlo en el directorio raiz de nuestro servidor, el ejemplo que muestro es para Apache (y es necesario tener mod-rewrite), y crear un archivo .htaccess que contenga lo siguiente:

1
2
3
4
RewriteEngine On
RewriteBase /
RewriteRule ^(.*\.css) tcjs.php?type=css&amp;file=$1
RewriteRule ^(.*\.js) tcjs.php?type=js&amp;file=$1

También tenemos que prestar atención a las primeras líneas de código del script tcjs.php:

  • $base_directory será el directorio raiz de todos los css, js, definiciones y caches (no es estrictamente necesario que sea de estos últimos). Es decir, si nuestra web está en /home/www/public_http/ no debemos llamar a nada que esté en un nivel inferior (podrán estar dentro de subdirectorios pero a partir de este punto); es más, los CSS y JS estarán por ejemplo en /home/www/public_http/js; en este caso $base_directory=’/home/www/public_http/
  • $httppath será la dirección web de menor nivel que vayamos a llamar; por ejemplo: http://www.midominio.com/
  • $cachedir será el lugar donde creemos los ficheros de caché, este directorio tiene que tener permisos para que el servidor web pueda escribir en él.
  • $excluded_files será el nombre de un archivo cuyo contenido serán todos los ficheros que no queramos que sean procesados, sólo serán comprimidos. Por ejemplo, si el fichero es /home/www/public_http/js/nieve.js y nuestro $base_directory es /home/www/public_http/, el texto que deberíamos incluir en el archivo será js/nieve.js
  • $definiciones_file es la ruta relativa a un archivo PHP que se cargará cuando vayamos a generar un CSS o JS. Puede haber dos tipos de archivo de definiciones, el global, situado en $base_directory.$definiciones_file y el local situado en (el mismo directorio que el archivo CSS a procesar).$definiciones_file. Por ejemplo:
    • $base_directory=’/home/www/public_http/’
    • El fichero JS que cargamos estará en /home/www/public_http/js/mijavascript.js
    • $definiciones_file=’defs/definiciones.php
    • tcjs.php cargará dos ficheros de definiciones situados en /home/www/public_http/defs/definiciones.php y en /home/www/public_http/js/defs/definiciones.php

El fichero de definiciones (que ya hemos visto donde está contendrá un array llamado $definiciones, pero no lo crearemos de nuevo, sino que lo continuaremos, por ejemplo:

1
2
3
4
...
$definiciones['color_base'] = '0ff00f';
$definiciones['ruta_static'] = 'http://estaticos.miservidor.com/';
$definiciones['visibilidad_mensajes'] = ($debug)?'visible':'hidden';

Podemos utilizarlo por ejemplo para definir un color de objeto desde PHP y que el CSS lo incluya (puede que debamos usarlo desde PHP también, por ejemplo para generar una imagen con ese color de fondo); para una ruta de ficheros estáticos en un servidor (normalmente en mi servidor local será otra ruta), para mostrar directamente una capa que está oculta mientras estamos programando algunas opciones en Javascript, y para muchas cosas más.

Atención Bill Gates ha tenido que hacerse el café esta mañana

Miércoles, 20 de Enero de 2010 admin Sin comentarios

Hoy me he levantado con la noticia de que Bill Gates (antiguo CEO de Microsoft y un multimillonario donde los haya), se ha hecho una cuenta de Twitter. Y en unas horas tiene más de medio millón de seguidores. (@BillGates).

Lo curioso es que su primer twit fue: “Hello world!”, y lo más curioso es que durante el día de hoy Twitter está saturado, y creo que sé quién tiene la culpa.

De todas formas, yo no le seguiré; si dice algo interesante, seguro que le hacen miles de retwits…

Barra al final del directorio en PHP: 4 formas a elegir

Lunes, 18 de Enero de 2010 admin Sin comentarios

Cuando queremos representar un directorio; podemos obtenerlo de varias formas: /home/usuario/documentos en *nix o C:\Document and Settings\Usuario\Mis Documentos en Windows. Aunque lo mismo podemos representarlo /home/usuario/documentos/ y C:\Document and Settings\Usuario\Mis Documentos\ (es lo mismo, pero con una barra al final).

El problema en PHP, viene a la hora de llamar archivos de ese directorio, hay ocasiones en las que no sabemos si la variable en donde tenemos almacenado el directorio tiene barra al final o no; entonces debemos hacer alguna función que incluya la barra correspondiente si hace falta.

Estos dos primeros script los he sacado de Jonas John Code Snippets:

1
2
3
4
5
6
7
8
9
10
11
12
function add_ending_slash($path){
 
    $slash_type = (strpos($path, '\')===0) ? 'win' : 'unix';  
    $last_char = substr($path, strlen($path)-1, 1);
 
    if ($last_char != '/' and $last_char != '\') {
        // no slash:
        $path .= ($slash_type == 'win') ? '\' : '/';
    }
 
    return $path;
}
1
2
3
4
5
6
7
8
9
10
11
12
function normalize_path($path){
 
    // DIRECTORY_SEPARATOR is a system variable
    // which contains the right slash for the current
    // system (windows = \ or linux = /)
 
    $s = DIRECTORY_SEPARATOR;
    $path = preg_replace('/[\/\\\]/', $s, $path);
    $path = preg_replace('/'.$s.'$/', '', $path) . $s;
 
    return $path;
}

Para este último, tenemos que hacer antes:

1
define("DIRECTORY_SEPARATOR", (PHP_OS=='Windows') ? '\':'/';

Otras dos alternativas:

1
2
3
4
5
6
function ending_slash($path)
{
  $sep = (PHP_OS == 'Windows')? '\':'/';
  $path .= (substr($path,-1) == $sep)? '':$sep;
  return $path;
}
1
2
3
4
5
6
7
function ending_slash2($path)
{
  $sep = (PHP_OS == 'Windows')? '\':'/';
  if ($path)
    $path .= ($path[strlen($path)-1] == $sep)? '':$sep;
  return $path;
}

La última no es muy elegante, pero ahí queda. Las dos últimas son muy parecidas entre sí. Y es una función interesante para nuestra biblioteca de funciones particular.

Categories: PHP Tags: , , , , ,

Me duelen los ojos… con el anuncio de Urende

Domingo, 17 de Enero de 2010 admin Sin comentarios

Avajo los precios :S:S:SMe duelen los ojos. Hoy he pasado por una de las tiendas de esta cadena (venden electrodomésticos, ordenadores, y tienen relación con la tecnología algunos de sus productos, y por eso lo pongo en este blog).

Justo antes de entrar, estuve a punto de irme, con esos dedos índice y corazón de la mano de algún inocente colocaos como si fuera una V, para formar la palabra avajo.

No dejaba de preguntarme si no estaba en Mediamarkt, por aquello de: Yo no soy tonto… igual que el anuncio de Zapatero; querían sumarse al número de talibanes ortográficos o considerarnos analfabetos a los amantes de la tecnología. Creo que éstos han caído demasiado bajo intentando llamar la atención.

Asignar valores a variables enteras en binario

Viernes, 15 de Enero de 2010 admin Sin comentarios

Hace unos meses, un alumno a quien le di clases particulares de C me preguntaba acerca de la asignación de valores en binario; y me decía que tanto si asignaba un valor en binario, como en hexadecimal, octal, etc; al ver su valor siempre era en decimal (printf(”%d”,valor);)

Las variables numéricas simplemente almacenan el número, que en definitiva, en memoria será un chorro de ceros y unos, y es a la hora de mostrarlo en pantalla como tenemos que decirle al sistema cómo lo muestra.

En C, se permite la introducción de datos en octal, decimal y hexadecimal (el binario no se usa mucho, además su transformación desde y hacia hexadecimal es casi inmediata).

En este código tenemos ejemplos para introducir datos en octal y hexadecimal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include

int main()
{
int numero;
numero=021;         /* Introducimos número en octal */
printf("Numero en decimal: %d\n",numero);
printf("Numero en octal: %o\n",numero);
printf("Numero en hexa: %X\n",numero);
printf("\n\n");
numero=0x28b;           /* Introducimos número en hexa */
printf("Numero en decimal: %d\n",numero);
printf("Numero en octal: %o\n",numero);
printf("Numero en hexa: %X\n",numero);
}

Pero no disponemos de nada para binario, y a lo mejor alguna vez nos es útil, imaginémonos que estamos haciendo un programa para un microcontrolador y tenemos que reducir el uso de memoria por ejemplo, o hacer un envío de datos por un bus con un protocolo determinado; y aunque sea fácil definir los datos en hexadecimal, a veces para una prueba y con prisas no queremos perder tiempo haciendo cálculos.

Aquí muestro un programa (necesita de la función decToBin) que genera una serie de defines con valores binarios de un número de bits especificado. Todo ello lo almacena en un archivo de cabecera (.h) para incluirlo en nuestros proyectos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include
#include

#define numbits 16

int *decToBin(int decimal, int nBits, int binary[]);  // No incluida en el ejemplo
void bin2file(FILE *f, int num);

int main()
{
int numero;
FILE *f;
int maxn=pow(2,numbits);

f=fopen("binarios.h", "w+");
if (f)
{
for (numero=0; numero
bin2file(f, numero);
}
else
printf("No puedo abrir el archivo!!");
return 0;
}

void bin2file(FILE *f, int num)
{
int binary[numbits];
int i;

decToBin(num, numbits, binary);
fputs("#define b", f);
for (i=0; i
fprintf(f, "%d", binary[i]);

fprintf(f, " %d\n", num);
}
Categories: General Tags:
Easy AdSense by Unreal