Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - do-while

#531
¡Buenas!

Estoy conectado a internet a través de mi smartphone con una conexión capada a 16 KB/s. Si mientras estoy ejecutando el gestor de descargas intento acceder a alguna web y esta es un poco pesada (con alguna imagen un poco pesada, varias imágenes o algún video) el gestor pierde todo el ancho de banda, me da error en la transferencia del archivo y tengo que volver a reiniciar la descarga.

¿Existe alguna forma de asegurar un ancho de banda mínimo para el gestor y repartir el resto de la conexión entre el resto de las aplicaciones?

(Intentaría googlear, pero google se me come todo el ancho de banda...)

¡Saludos!
#532
¡Buenas!

Acabo de ver la noticia y todavía no he googleado para buscar información, pero ¿alguno sabéis si la empresa es estadounidense?

¡Saludos!
#533
¡Buenas!


Había leido que de las operaciones "elementales" (+, -, * , / y %), las que mas le costaban al procesador eran / y %, la división, y efectivamente:

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

#define MAX 10000000000LLU

int main(int argc, char *argv[])
{
    unsigned long long i,x,y;
    time_t ini;

    ini = time(NULL);

    for(i = 0 ; i < MAX ; i++)
        if(i % 2);

    printf("%lu segundos\n", time(NULL) - ini);

    ini = time(NULL);

    for(i = 0 ; i < MAX ; i++)
        if(i & 1);

    printf("%lu segundos\n", time(NULL) - ini);

    return 0;
}


Se nota la diferencia, pero para que sea considerable, he tenido que llegar a 10^10 iteraciones...

Aun así, se ve que es preferible comprobar el bit menos significativo en un código que requiera continuamente la comprobación de la paridad de un numero a utilizar el operador módulo.

¡Saludos!
#534
Cita de: 0xDani en 21 Julio 2013, 00:49 AM
EDIT: Estos tíos sí que lo flipaban con la optimización: http://www.thehackademy.net/madchat/vxdevl/vxmags/ddt-1/DDT%231.2_G

Aunque he leído muy poco, el texto parece entretenido. A ver que se cuentan.

Un amigo está haciendo un trabajo sobre como los compiladores de C (no se si se centra en gcc...) traducen a código máquina y, por lo que me dijo, hay diferencias entre variable++, ++variable,variable = variable + 1 y variable += 1. No se si todas las expresiones anteriores generan distinto código máquina o si alguna es equivalente a alguna de las otras... ¿Sabéis algo mas sobre esto?

¡Saludos!

Acabo de leerlo. No me parece demasiado interesante. Se centra sobre todo en reducir la cantidad de código máquina generado. No busca reducir el coste computacional del algoritmo. Si el código inicial tiene un orden O(n), el final tendrá el mismo, por lo que desde el punto de vista del algoritmo, no gana nada...
#535
¡Buenas!

Esta mañana me he dedicado a perder el tiempo, así que comparto el tiempo perdido con vosotros y no tengo la sensación de haberlo perdido para nada.

Se trata de la sucesión de Fibonacci (ya conocida por todos (supongo)).

El algoritmo obtenido no es tan rápido como la versión iterativa (creo que anda cerca), pero mejora con creces la versión recursiva.

Evidentemente no es inmediata, como la formula que obtiene el enésimo termino en función de n y de phi (el numero aureo...)

Tampoco he utilizado programación dinamica, así que el único problema de memoria, si lo hubiese, estaría originado por una cantidad excesiva de llamadas recursivas.

Aquí os dejo un par de códigos. El primero con explicaciones sobre como se llega a la formula utilizada y con una comparación entre el algoritmo clásico y el optimizado, y el segundo para utilizarlo desde la linea de comandos, por si a alguien le hace ilusión.

¡Saludos!


/*
  JUGANDO UN POCO CON LA SUCESION DE FIBONACCI
  ============================================

  La sucesion de Fibonacci se define de forma recursiva como:

fibo(n) = n  si n = 0 ó 1
fibo(n) = fibo(n - 1) + fibo(n - 2) si n > 1

  Aplicar la recursion de esta forma hace que el numero de llamadas sea de orden
exponencial con respecto al tamaño inicial del dato, por lo que el algoritmo se
vuelve lento rapidamente.

  Suponiendo n suficientemente grande podemos descomponer fibo(n - 1) en el paso
de recurcion como sigue:

fibo(n) = fibo(n - 1) + fibo(n - 2) = (fibo(n - 2) + fibo(n - 3)) + fibo(n - 2) =
= 2 * fibo(n - 2) + fibo(n - 3)

  Aplicamos el mismo proceso a fibo(n - 2):

fibo(n) = 2 * fibo(n - 2) + fibo(n - 3) = 2 * (fibo(n - 3) + fibo(n - 4)) + fibo(n - 3) =
= 3 * fibo(n - 3) + 2 * fibo(n - 4)

  Y para ver las cosas mas claras lo repetimos con fibo(n - 3):

fibo(n) = 3 * fibo(n - 3) + 2 * fibo(n - 4) = 3 * (fibo(n - 4) + fibo(n - 5) + 2 * fibo(n - 4) =
= 5 * fibo(n - 4) + 3 * fibo(n - 5)

  Por si no queda claro donde queremos llegar resumimos lo que tenemos hasta ahora:

  Cada una de las siguientes expresion son iguales a fibo(n):

1 * fibo(n - 1) + 1 * fibo(n - 2) = fibo(2) * fibo(n - 1) + fibo(1) * fibo(n - 2) =
2 * fibo(n - 2) + 1 * fibo(n - 3) = fibo(3) * fibo(n - 2) + fibo(2) * fibo(n - 3) =
3 * fibo(n - 3) + 2 * fibo(n - 4) = fibo(4) * fibo(n - 3) + fibo(3) * fibo(n - 4) =
5 * fibo(n - 4) + 3 * fibo(n - 5) = fibo(5) * fibo(n - 4) + fibo(4) * fibo(n - 5)

  Si seguimos de esta forma podemos intuir que

  fibo(n) = fibo(k + 1) * fibo(n - k) + fibo(k) * fibo(n - k - 1) := F(n,k) para 0 <= k < n

  Se puede demostrar por induccion que fijando un N natural (N >= 2) se tiene que

  fibo(N) = F(N,k) para todo 0 <= k < N

  y que fijado K natural para todo n > K se tiene que

  fibo(n) = F(n,K)

  por lo tanto tenemos:

  fibo(n) = F(n,k) = fibo(k + 1) * fibo(n - k) + fibo(k) * fibo(n - k - 1) para 0 <= k < n


  SUCESION DE FIBONACCI OPTIMIZADA
  ================================

  Escribiremos fibo(n) como  f(n), es mas corto :-)
  Partiendo de la expresion F(n,k) consideraremos dos casos:

  - n par:

        Sea k = n / 2

        Asi F(n,k) = f(k + 1) f(n - k) + f(k) f(n - k - 1) =
        f(n/2 + 1) f(n/2) + f(n/2) f(n/2 - 1) =
        =f(n/2) (f(n/2 + 1) + f(n/2 - 1)

        F(n,n/2) = f(n / 2) * (f(n / 2 + 1) + f(n / 2 - 1)) := F(n)

    - n impar:

        Sea k = (n - 1) / 2

        F(n,k) = f(k + 1) f(n - k) + f(k) f(n - k - 1) =
        f((n - 1) / 2 + 1) f((n + 1) / 2) + f((n - 1) / 2) f((n + 1) / 2 - 1) =
        f((n + 1) / 2) f((n + 1) / 2) + f((n - 1) / 2) f((n - 1) / 2) =
        (f((n + 1) / 2))^2 + (f((n - 1) / 2))^2

        F(n,(n - 1)/2) = (f((n + 1) / 2))^2 + (f((n - 1) / 2))^2 := F(n)

    Por lo tanto definimos la sucesion de Fibonacci como sigue:

    fibo(0) = 0
    fibo(1) = 1
    fibo(n) = F(n) si n > 1

    donde:
        F(n) = fibo(n / 2) * (fibo(n / 2 + 1) + fibo(n / 2 - 1)) si n par
        F(n) = (fibo((n + 1) / 2))^2 + (fibo((n - 1) / 2))^2     si n impar

    Observemos ahora que si n==2,

    fibo(2) = F(2) = fibo(1) * (fibo(2) + fibo(0)) = fibo(1) * fibo(2)

    y tenemos una recursion infinita, ya que para calcular fibo(2) hay que calcular fibo(2)...

    Asi pues, tenemos la definicion final de la sucesion de Fibonacci:

    fibo(0) = 0
    fibo(1) = 1
    fibo(2) = 1
    fibo(n) = F(n) si n > 1

    con F(n) como antes.

    Definiendo fibo(n) de esta forma, en cada paso de recursion generamos dos o tres llamadas
    a la misma funcion fibo, pero en cada una de ellas reducimos el tamaño del dato inicial a
    la mitad, por lo que el coste computacional es mucho menor (¿Cual es el coste? No se calcularlo)
*/

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

#define MIN 37
#define MAX 42

typedef unsigned long long fibo_t;

unsigned long long llamadas_clasico;
unsigned long long llamadas_optimizado;

fibo_t fibo_clasico(fibo_t n)
{
    llamadas_clasico++;

    if(n == 0)
        return 0;
    if(n == 1)
        return 1;

    return fibo_clasico(n - 1) + fibo_clasico(n - 2);
}

fibo_t fibo(fibo_t n)
{
    llamadas_optimizado++;

    if(n == 0)
        return 0;
    if(n == 1)
        return 1;
    if(n == 2) //Evitamos recurion infinita si n == 2
        return 1;

    if(n % 2) //n impar y mayor que 2
    {
        fibo_t k1,k2;

        k1 = fibo((n + 1) / 2);
        k2 = fibo((n - 1) / 2);

        return k1 * k1 + k2 * k2;
    }

    //n par y mayor que 2
    return fibo(n / 2) * (fibo((n / 2) + 1) + fibo((n / 2) - 1));
    //si n == 2 fibo(n / 2) * fibo(n / 2 + 1) = fibo(1) * fibo(2)
    //habria recursion infinita si no se pone n == 2 como caso base
}

int main(int argc, char *argv[])
{
    fibo_t i,valor;
    time_t ini;

    printf("Fibonacci clasico:\n");

    ini = time(NULL);

    for(i = MIN ; i < MAX ; i++)
    {
        llamadas_clasico = 0;
        valor = fibo_clasico(i);

        printf("  fibo_clasico(%llu) = %llu (%llu llamadas)\n",i,valor,llamadas_clasico);
    }

    printf("%llu segundos\n",time(NULL) - ini);

    printf("\nFibonacci optimizado:\n");

    ini = time(NULL);

    for(i = MIN ; i < MAX ; i++)
    {
        llamadas_optimizado = 0;
        valor = fibo(i);

        printf("  fibo(%llu) = %llu (%llu llamadas)\n",i,valor,llamadas_optimizado);
    }

    printf("%llu segundos\n",time(NULL) - ini);

    return 0;
}



#include <stdio.h>

typedef unsigned long long fibo_t;

fibo_t fibo(fibo_t n)
{
    if(n == 0)
        return 0;
    if(n == 1)
        return 1;
    if(n == 2)
        return 1;

    if(n % 2)
    {
        fibo_t k1,k2;

        k1 = fibo((n + 1) / 2);
        k2 = fibo((n - 1) / 2);

        return k1 * k1 + k2 * k2;
    }

    return fibo(n / 2) * (fibo((n / 2) + 1) + fibo((n / 2) - 1));
}

int convertir(char *s, fibo_t *valor)
{
    *valor = 0;

    while(*s)
    {
        if((*s) < '0' || (*s) > '9')
        {
            *valor = 0;
            return 0;
        }

        *valor *= 10;
        *valor += (*(s++)) - '0';
    }

    return 1;
}

int main(int argc, char *argv[])
{
    int i;
    fibo_t n;

    if(argc < 2)
    {
        fprintf(stderr,"\nLinea de comandos: %s PARAMETRO_1 [PARAMETRO_2 ... PARAMETRO_N]\n\n",argv[0]);
        fprintf(stderr,"Los distintos parametros deben ser enteros positivos\n");
        return 1;
    }

    fprintf(stdout,"\n");

    for(i = 1 ; i < argc ; i++)
    {
        if(!convertir(argv[i],&n))
            fprintf(stderr,"%s: parametro incorrecto\n",argv[i]);
        else
            fprintf(stdout,"%s(%llu) = %llu\n",argv[0],n,fibo(n));
    }

    return 0;
}
#536
Foro Libre / Re: Cultura General
17 Julio 2013, 10:26 AM
Te respondo con otra pregunta (la respuesta a ambas preguntas es la misma)

¿Cuantos meses tienen 28 días?
#537
¡Buenas!

Vaya, un conocido mío murió de muerte súbita cardíaca mientras jugaba un partido de futbito con unos amigos. Yo pensaba que la culpa era del deporte y no de los videojuegos.

Es mas, a un familiar cercano le dio un infarto cuando se disponía a cambiar de acera (absteneos de comentarios zafios...). Creo que la gente debería de pensárselo dos veces antes de tomar tan arriesgada decisión.

Dormir también es una actividad de riesgo. A lo largo del tiempo, ¿Cuanta gente muere mientras duerme? ¿Eh?

Otra cosa que deberían prohibir es vivir. Según un estudio medico del departamento de ensayos aleatorios y estadística absurda aplicada de la Universidad de Cantalapiedra de Arriba, la principal causa de muerte es la vida.

Así que andaos con mas ojo con lo que hacéis en esta vida, que la muerte está al acecho en cada esquina...

¡Saludos!
#538
¡Buenas!

Gracias por contestar. Efectivamente. Tengo desactivadas cookies...  :silbar:

Y si. Es como lo han explicado. Sale un aviso (una especie de message box) con la opcion de descarga de la aplicacion desde la play store.

¡Saludos y gracias de nuevo!
#539
(He corregido algun error que había en alguna cadena. Ahora si que creo que está todo bien)

He añadido comprobación de parámetros en la función vigenere, que es donde deberían estar si se quiere añadir a una librería.

Ahora, en lugar de definir un nombre de fichero temporal mediante una constante simbolica, utilizo tmpnam() para asegurarme de que el nombre no se corresponda con ningún archivo existente.

¡Buenas!

Como estáis recopilando códigos de cifrado, aquí os dejo el del cifrado de Vigenere.

El código es un podo largo. El cifrado de Vigenere está al principio. Hay repeticion de código, pero lo he hecho así para evitar introducir demasiadas condiciones en el codigo de cifrado, ya que para archivos extensos el algoritmo sería muy lento. El codigo que hay en main es basicamente para leer y clasificar los datos de la linea de comandos (por eso es tan largo). Al final os dejo la sintaxis de llamada desde la linea de comandos y algunos ejemplos:


/*
* Cifrado de Vigenere
*
* Linea de comandos: nombre_programa -a alfabeto -[c|f] cadena|fichero -k clave -s [fichero_salida | std]
*
* Cifra los caracteres de la cadena (parametros -c "Cadena") o el fichero (parametros -f nombre_del_fichero)
* que coincidan con los del alfabeto (- que se le pasa, utilizando la clave dada (parametros -k clave)
*
*/

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

#define MAX_STRLEN 256

/*
* Las siguientes constantes sirven para decidir si la funcion vigenere actuara sobre una cadena o un fichero
*/
#define IN_CADENA  0
#define IN_FICHERO 1

/*
* Constantes para decidir si la funcion vigenere cifrara o descifrara la entrada
*/
#define ACCION_CIFRAR    0
#define ACCION_DESCIFRAR 1

/*
* vigenere(tipo entrada (cadena o fichero), cadena con texto o nombre de fichero con el input,
* alfabeto, clave, cifrar|descifrar, fichero de salida (stdin o nombre de arcivo))
*
* valor de retorno: 0 si algo falla, 1 si todo va bien.
*/

unsigned long flen(FILE *f)
{
    unsigned long pos,len;

    pos = ftell(f);
    fseek(f,0,SEEK_END);
    len = ftell(f);
    fseek(f,pos,SEEK_SET);

    return len;
}

int vigenere(int modo_input, char *cadena, char *alfabeto, char *clave, char accion, FILE *salida)
{
    FILE *entrada = NULL;
    unsigned long longitud,tam_bloque,tam_clave,tam_alfabeto;
    char *lector,*busqueda;
    int *desplazamiento,i,indice = 0;

    /* comprobamos que en alfabeto no haya letras repetidas */
    for(i = 0 ; alfabeto[i] ; i++)
        if(strchr(alfabeto + i + 1,alfabeto[i]))
            return 0;

    /* comprobamos que los caractreres de la clave esten en el alfabeto */
    for(i = 0 ; clave[i] ; i++)
        if(!strchr(alfabeto,clave[i]))
            return 0;

    if(modo_input == IN_CADENA)
        longitud = strlen(cadena);
    else if(modo_input == IN_FICHERO)
    {
        if(!(entrada = fopen(cadena,"rb")))
            return 0;

        longitud = flen(entrada);
    }
    else
        return 0;

    tam_alfabeto = strlen(alfabeto);
    tam_clave = tam_bloque = strlen(clave);

    if(!(lector = malloc(tam_bloque * sizeof(char))))
        return 0;

    if(!(desplazamiento = malloc(tam_bloque * sizeof(int))))
    {
        free(lector);
        return 0;
    }

    for(i = 0 ; clave[i] ; i++)
    {
        if(!(busqueda = strchr(alfabeto,clave[i])))
        {
            free(lector);
            free(desplazamiento);

            return 0;
        }

        if(accion == ACCION_CIFRAR)
            desplazamiento[i] = busqueda - alfabeto;
        else if(accion == ACCION_DESCIFRAR)
            desplazamiento[i] = alfabeto - busqueda; /* el desplazamiento de descifrado es el opuesto del de cifrado */
        else
        {
            free(lector);
            free(desplazamiento);

            return 0;
        }
    }

    if(modo_input == IN_CADENA)
    {
        while(longitud)
        {
            if(longitud < tam_bloque)
                tam_bloque = longitud;

            memcpy(lector,cadena,tam_bloque * sizeof(char));

            for(i = 0 ; i < tam_bloque ; i++)
            {
                if(busqueda = strchr(alfabeto,lector[i]))
                {
                    lector[i] = alfabeto[((busqueda - alfabeto) + desplazamiento[indice] + tam_alfabeto) % tam_alfabeto];
                    indice = (indice + 1) % tam_clave;
                }
            }

            fwrite(lector , tam_bloque*sizeof(char) , 1 , salida);

            if((tam_bloque == tam_clave) && (longitud > tam_bloque))
                cadena += tam_bloque;

            longitud -= tam_bloque;
        }
    }
    else if(modo_input == IN_FICHERO)
    {
        while(longitud)
        {
            if(longitud < tam_bloque)
                tam_bloque = longitud;

            fread(lector,tam_bloque * sizeof(char),1,entrada);

            for(i = 0 ; i < tam_bloque ; i++)
            {
                if(busqueda = strchr(alfabeto,lector[i]))
                {
                    lector[i] = alfabeto[((busqueda - alfabeto) + desplazamiento[indice] + tam_alfabeto) % tam_alfabeto];
                    indice = (++indice) % tam_clave;
                }
            }

            fwrite(lector , tam_bloque*sizeof(char) , 1 , salida);

            longitud -= tam_bloque;
        }
    }
    else
    {
        if(entrada)
            fclose(entrada);

        free(lector);
        free(desplazamiento);

        return 0;
    }

    if(entrada)
        fclose(entrada);

    free(lector);
    free(desplazamiento);

    return 1;
}

int main(int argc, char *argv[])
{
    char error[] = "%s [+|-]c (cifrar|descifrar) -a alfabeto -[s|f] [cadena|fichero] -k clave -o [fichero_salida|std]\n";
    char alfabeto[MAX_STRLEN] = "", fentrada[MAX_STRLEN] = "", clave[MAX_STRLEN] = "", fsalida[MAX_STRLEN] = "";
    char *texto = NULL,*ftemp = NULL;
    int sobreescribir = 0, modo = ACCION_CIFRAR + ACCION_DESCIFRAR + 1, i, j;
    FILE *f;

    if(argc != 10)
    {
        fprintf(stderr,error,argv[0]);
        return 1;
    }

    for(i = 1 ; i < 10 ; i += 2)
    {
        if(!strcmp(argv[i],"-a"))
        {
            if(strlen(alfabeto))
            {
                fprintf(stderr,"-a: Parametro repetido\n");
                return 2;
            }

            if(!strlen(argv[i + 1]))
            {
                fprintf(stderr,"-a: Alfabeto vacio no permitido\n");
                return 3;
            }

            for(j = 0 ; argv[i + 1][j] ; j++)
            {
                if(strchr(argv[i + 1] + j + 1, argv[i + 1][j]))
                {
                    fprintf(stderr,"-a: No se permiten caracteres repetidos en el alfabeto\n");
                    return 4;
                }
            }

            if(strlen(argv[i + 1]) >= MAX_STRLEN)
            {
                fprintf(stderr,"-a: El alfabeto es demasiado largo. Se truncara a partir del caracter %d.\n",MAX_STRLEN);

                strncpy(alfabeto, argv[i + 1], 255);
                alfabeto[255] = '\0';
            }
            else
                strcpy(alfabeto,argv[i + 1]);
        }
        else if(!strcmp(argv[i],"-s"))
        {
            if(texto || strlen(fentrada))
            {
                fprintf(stderr,"-s: Parametro -[s|f] repetido\n");
                return 5;
            }

            texto = argv[i + 1];
        }
        else if(!strcmp(argv[i],"-f"))
        {
            if(texto || strlen(fentrada))
            {
                fprintf(stderr,"-f: Parametro -[s|f] repetido\n");
                return 6;
            }

            if(strlen(argv[i + 1]) >= MAX_STRLEN)
            {
                fprintf(stderr,"-f: El nombre del fichero de entrada no debe exceder los %d caracteres\n",MAX_STRLEN);
                return 7;
            }

            if(!strlen(argv[i + 1]))
            {
                fprintf(stderr,"-f: El nombre del fichero de entrada no puede estar vacio\n");
                return 8;
            }

            strcpy(fentrada,argv[i + 1]);
        }
        else if(!strcmp(argv[i],"-k"))
        {
            if(strlen(clave))
            {
                fprintf(stderr,"-k: Parametro -k repetido\n");
                return 9;
            }

            if(!strlen(argv[i + 1]))
            {
                fprintf(stderr,"-k: No se permiten claves vacias");
                return 10;
            }

            if(strlen(argv[i + 1]) >= MAX_STRLEN)
            {
                fprintf(stderr,"-k: La clave no debe exceder los %d caracteres\n",MAX_STRLEN);
                return 11;
            }

            if(!strlen(argv[i + 1]))
            {
                fprintf(stderr,"-k: La clave no puede ser vacia\n");
                return 12;
            }

            strcpy(clave,argv[i + 1]);
        }
        else if(!strcmp(argv[i],"-o"))
        {
            if(strlen(fsalida))
            {
                fprintf(stderr,"-o: Parametro -o repetido\n");
                return 13;
            }

            if(strlen(argv[i + 1]) >= MAX_STRLEN)
            {
                fprintf(stderr,"-o: El nombre del fichero de salida no debe exceder los %d caracteres\n",MAX_STRLEN);
                return 14;
            }

            if(!strlen(argv[i + 1]))
            {
                fprintf(stderr,"-o: El nombre del fichero de salida no puede estar vacio\n");
                return 15;
            }

            strcpy(fsalida,argv[i + 1]);
        }
        else if(!strcmp(argv[i],"-c"))
        {
            if(!(modo ^ ACCION_CIFRAR) || !(modo ^ ACCION_DESCIFRAR))
            {
                fprintf(stderr,"-c: Parametro [+|-]c repetido\n");
                return 16;
            }

            modo = ACCION_DESCIFRAR;
            i--; /* este argumento no tiene asociado un parametro */
        }
        else if(!strcmp(argv[i],"+c"))
        {
            if(!(modo ^ ACCION_CIFRAR) || !(modo ^ ACCION_DESCIFRAR))
            {
                fprintf(stderr,"+c: Parametro [+|-]c repetido\n");
                return 17;
            }

            modo = ACCION_CIFRAR;
            i--; /* este argumento no tiene asociado un parametro */
        }
        else
        {
            fprintf(stderr,error,argv[0]);
            return 18;
        }
    }

    //comprobar que los caracteres de la clave estan en el alfabeto
    for(i = 0 ;  clave[i] ; i++)
    {
        if(!strchr(alfabeto,clave[i]))
        {
            fprintf(stderr,"La clave contiene caracteres que no aparecen en el alfabeto\n");
            return 19;
        }
    }

    if(!strcmp(fsalida,"std"))
    {
        f = stdout;
    }
    else
    {
        if(f = fopen(fsalida,"r"))
        {
            char opcion;

            do{
                printf("El fichero de salida ya existe. Deseas sobreescribirlo? (S/N) ");
                opcion = getchar();

                if(opcion > 'Z')
                    opcion += 'S' - 's';

                while(getchar() != '\n');

            }while(opcion!= 'S' && opcion!='N');

            if(opcion == 'S')
            {
                fclose(f);

                ftemp = tmpnam(NULL);

                if(!(f = fopen(ftemp,"wb")))
                {
                    fprintf(stderr,"%s: Error al abrir el fichero de salida\n",argv[0]);
                    return 20;
                }
                sobreescribir = 1;
            }
            else
            {
                fclose(f);
                return 0;
            }
        }
        else
            f = fopen(fsalida,"wb");
    }

    //si fsalida == std llamar a vigenere con los parametro y fsalida stdout
    if(texto)
    {
        if(!vigenere(IN_CADENA,texto,alfabeto,clave,modo,f))
        {
            fprintf(stderr,"%s no ha podido cifrar la informacion dada\n",argv[0]);
            return 21;
        }
    }
    else
    {
        if(!vigenere(IN_FICHERO,fentrada,alfabeto,clave,modo,f))
        {
            fprintf(stderr,"%s no ha podido cifrar la informacion dada\n",argv[0]);
            return 21;
        }
    }

    if(strcmp(fsalida,"std"))
        fclose(f);

    if(sobreescribir)
    {
        remove(fentrada);
        rename(ftemp,fentrada);
        remove(ftemp);
    }

    return 0;
}


Sintaxis (mi programa se llama vigenere.exe):

vigenere [+|-]c (cifrar|descifrar) -a alfabeto -[s|f] [cadena|fichero] -k clave -o [fichero_salida|std]

+c cifrar
-c descifrar

-a "alfabeto de cifrado": Los caracteres que se consideraran para cifrar.

-s "cadena": La entrada es la cadena que sigua a -s
-f "fichero": La entrada se tomara del nombre de fichero que siga a -f

-k "clave": Indicara el desplazamiento de los caracteres del texto en claro

-o "fichero": La salida se producira en el fichero indicado.
-o std: La salida se producira por pantalla.


Ejemplos:

vigenere +c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "el simbolo de la suma es + y el de la resta -" -k "ejemplo de clave" -o std

iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j


vigenere +c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "el simbolo de la suma es + y el de la resta -" -k "ejemplo de clave" -o prueba.txt

type prueba.txt
iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j


vigenere -c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j" -k "ejemplo de clave" -o std

el simbolo de la suma es + y el de la resta -

vigenere -c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -f prueba.txt -k "ejemplo de clave" -o std

el simbolo de la suma es + y el de la resta -


El orden de los argumentos no tiene que ser el que he utilizado yo, puede ser cualquier otro.

¡Saludos!

PD:

El codigo ensablador que ha dejado cpu2 sigue la sintaxis Intel. GCC utiliza sintaxis AT&T (creo).

cpu2, ¿podrías traducir tu código de Intel a AT&T?
#540
Cita de: beholdthe en 22 Junio 2013, 05:12 AMtenemos que ver como las leyes que están hechas para todos por igual, a la hora de la verdad, no se aplican de igual modo.

Cierto.

Como bien dice un amigo mío, "Todos somos iguales ante la ley, pero unos mas que otros". No tiene sentido lógico, pero el significado se entiende.

¡Saludos!