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

#851
XD

        if (d==1)
        {
            May=Men=N1;
        }


Asi te aseguras que tento May com Men son valores que has introducido.

¡Saludos!
#852
¡Buenas!

En el primer programa tienes un pequeño error de logica, al asignar el primer valor haces bien asignando al maximo ese primer valor, pero a minimo le das como valor 1, por lo tanto, si cualquier otro numero es mayor que uno tendras un falso valor minimo de 1, por lo tanto, tendras que hacer maximo = minimo = primer_valor_introducido.

El segundo codigo es algo horroroso sin pies ni cabeza, ya que si todos los numeros introducidos son negativos tendras a cero como falso maximo y si todos los valores son mayores que el que has estimado tu como minimo tendras un falso minimo, por lo tanto ese codigo es completamente incorrecto ya que no soluciona todos los casos que te podras encontrar.

¡Saludos!
#853
¡Buenas!

He visto que ultimamente hay bastantes preguntas sobre memoria dinamica. Aqui os dejo un pequeño programa que la utiliza varias veces y con distintos tipos de puntero. Espero que podais usarlo como ejemplo para resover vuestros propios problemas.

Para los interesados en criptografia, tengo que decir que es una variante del cifrado de Beaufort en el que se pueden utilizar varias claves para añadir seguridad al cifrado:


/*

    Utilidad que cifra ficheros basandose en el cifrado de Beaufort con claves multiples

    Al ultilzar claves multiples, la longitud de la clave resultante sera el minimo comun
multiplo de todas las claves utilizadas.

    cifra +|- "claves" fichero_de_entrada fichero_de_salida

    +: cifrar
    -: descifrar

*/

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

/* funcion que guarda en tokens las palabras contenidas en s y devuelve el numero de parabras extraidas */
int tokenize(char *s, char ***tokens);

/* carga en (*s) el contenido del fichero al que apunta f */
unsigned long cargar_fichero(FILE *f, unsigned char** s);

/*

calcula el coeficiente nsimo segun el siguiene criterio:

ultima_clave[posicion % longitud ultima_clave] -
penultima_clave[posicion % longitud penuultima_clave] +
antepenultima_clave[posicion % longitud antepenultima_clave] +
... + o - (segun el numero de claves) primera_clave[posicion % longitud primera_clave]
*/
int coeficiente(unsigned long posicion, char **claves, int nclaves);

/*
    cifrado[i] = coeficiente[i] + o - (depende del numero de claves) texto_plano[i] mod 256;

    tomando la clase de quivalencia positiva entre 0 y 255
*/
int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);


/*
    texto_plando[i] = 1 o (-1) (depende del numero de claves) * (cifrado[i] - coeficiente[i]) mod 256;

    tomando la clase de quivalencia positiva entre 0 y 255
*/
int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);

/*

    las siguientes funciones calculan el minimo comun multiplo y maximo comun divisor de dos enteros

*/
unsigned long mcm(unsigned long a, unsigned long b);
unsigned long mcd(unsigned long a, unsigned long b);

int main(int argc, char *argv[])
{
    FILE *f; /* fichero de entrada y de salida */
    char **claves = NULL; /* variable para guardar las claves introducidas */
    unsigned char *contenido = NULL; /* puntero para almacenar el contenido del fichero */
    unsigned long longitud, nclaves; /* longitud del fichero y numero de claves introducidas*/

    if(argc != 5)
    {
        printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
    }
    else
    {
        if(!(f = fopen(argv[3] , "rb")))
            printf("No se puede abrir el fichero: %s\n", argv[3]);
        else
        {
            if((longitud = cargar_fichero(f,&contenido)) == (unsigned long)(-1))
            {
                printf("Ha ocurrido un error al cargar el contenido del fichero de entrada.\n");
                fclose(f);
            }
            else
            {
                if((nclaves = tokenize(argv[2] , &claves)) != (unsigned long)(-1))
                {
                    if(!strcmp(argv[1],"+"))
                    {
                        if(!cifrar(contenido,longitud,claves,nclaves))
                            printf("\nHa ocurrido un error en el proceso de cifrado.\n");
                        else
                        {
                            if(!(f = fopen(argv[4] , "wb")))
                                printf("No se puede abrir el fichero: %s\n", argv[4]);
                            else
                            {
                                fwrite(contenido,longitud,1,f);
                                fclose(f);
                            }
                        }

                        free(contenido);

                        for(longitud = 0 ; longitud < nclaves ; longitud++)
                            free(claves[longitud]);
                        free(claves);
                    }
                    else if(!strcmp(argv[1],"-"))
                    {
                        if(!descifrar(contenido,longitud,claves,nclaves))
                            printf("\nHa ocurrido un error en el proceso de descifrado.\n");
                        else
                        {
                            if(!(f = fopen(argv[4] , "wb")))
                                printf("No se puede abrir el fichero: %s\n", argv[4]);
                            else
                            {
                                fwrite(contenido,longitud,1,f);
                                fclose(f);
                            }
                        }

                        free(contenido);

                        for(longitud = 0 ; longitud < nclaves ; longitud++)
                            free(claves[longitud]);
                        free(claves);
                    }
                    else
                        printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
                }
                else
                {
                    printf("\nHa ocurrido un error al cargar las claves.\n");
                    free(contenido);
                }
            }
        }
    }

    return 0;
}

unsigned long cargar_fichero(FILE *f,unsigned char **ptr)
{
    unsigned long pos, len;

    /* calculamos la longitud del fichero */
    pos = ftell(f);
    fseek(f,0,SEEK_END);
    len = ftell(f);
    fseek(f,pos,SEEK_SET);

    /* asignamos tantos bytes como tenga el fichero */
    if(((*ptr) = (unsigned char *) malloc(len * sizeof(unsigned char))) != NULL)
        /* y cargamos el contenido */
        fread((*ptr),len,1,f);
    else
        len = (unsigned long)(-1);

    return len;
}

int tokenize(char *s, char ***tokens)
{
    char **aux; /* variable auxiliar para ir añadiendo una cadena mas a la lista */
    char *palabra; /* palabra extraida de la cadena s*/
    int npalabras = 0,i; /* numero de palabras y contador para bucles */

    /* intentamos leer una palabra */
    palabra = strtok(s," ");

    (*tokens) = NULL;

    while(palabra)
    {
        /* si se ha encontrado una palabra incrementamos el recuento de palabras*/
        npalabras++;

        /* hacemos que aux contenga tantos punteros a char como paralbras haya */
        if(!(aux = (char **) realloc((*tokens) , npalabras * sizeof(char*))))
        {
            for(i = 0 ; i < npalabras - 1 ; i++)
                free((*tokens)[i]);

            free(*tokens);
            (*tokens) = NULL;

            return -1;
        }
        else
        {
            /* asignamos la ultima palabra leida */
            aux[npalabras - 1] = (char *) malloc(sizeof(char) * (strlen(palabra) + 1));
            strcpy(aux[npalabras - 1] , palabra);

            /* y hacemos que la variable de entrada/salida apunte al nuevo conjunto de palabras */
            (*tokens) = aux;
        }

        /* intentamos leer la siguiente palabra */
        palabra = strtok(NULL , " ");
    }

    return npalabras;
}

int coeficiente(unsigned long posicion, char **claves, int nclaves)
{
    int c=0;
    unsigned long j;

    for(j = 0 ; j < nclaves ; j++)
    {
        if((nclaves - 1 - j) % 2)
            c -= claves[j][posicion % strlen(claves[j])];
        else
            c += claves[j][posicion % strlen(claves[j])];
    }

    return c;
}

int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
{
    unsigned long i;
    char *clave;
    unsigned long long_clave=1;

    /* la longitud de la clave final sera el mcm de las longitudes de las claves */
    for(i = 0 ; i < nclaves ; i++)
        long_clave = mcm(long_clave , strlen(claves[i]));

    if(!(clave = (char*) malloc(long_clave * sizeof(char))))
        return 0;

    for(i = 0 ; i < long_clave ; i++)
        clave[i] = coeficiente(i,claves,nclaves);

    for(i = 0 ; i < longitud ; i++)
        s[i] = (nclaves * 256 + (clave[i % long_clave] + (1 - 2 *(nclaves % 2)) * s[i])) % 256;

    free(clave);

    return 1;
}

int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
{
    unsigned long i;
    char *clave;
    unsigned long long_clave=1;

    for(i = 0 ; i < nclaves ; i++)
        long_clave = mcm(long_clave , strlen(claves[i]));

    if(!(clave = (char*) malloc(long_clave * sizeof(char))))
        return 0;

    for(i = 0 ; i < long_clave ; i++)
        clave[i] = coeficiente(i,claves,nclaves);

    for(i = 0 ; i < longitud ; i++)
        s[i] = (nclaves * 256 + ((1 - 2 * (nclaves % 2)) * (s[i] - clave[i % long_clave]))) % 256;

    free(clave);

    return 1;
}

unsigned long mcm(unsigned long a, unsigned long b)
{
    return (a * b) / mcd(a,b);
}

unsigned long mcd(unsigned long a, unsigned long b)
{
    if(a < b)
    {
        a ^= b;
        b ^= a;
        a ^= b;
    }

    if(!b)
        return a;

    return mcd(b , a % b);
}


Se debe utilizar desde la linea de comandos, por lo que es recomendable dejar el ejecutable en c:\windows\system32 para sistemas windows, \bin en sistemas UNIX y en general, en el directorio en el que se encuentren por defecto los comandos del sistema.

Para cifrar un fichero llamado "prueba" con la clave "clave de prueba" y como fichero de salida "cifrado", se debera hacer:

cifra + "clave de prueba" prueba cifrado

suponiendo que nombre del ejecutable sea cifra.

Para obtener el texto plano se utilizara la misma sintaxis utilizando el parametro - en lugar de +.

¡Saludos y espero que os sirva de referencia!

PD: Si veis algun error avisad, que uno es humano y por lo tanto propenso a cometer errores. Lo mismo si teneis alguna sugerencia.

¡Saludos!
#854
Foro Libre / Re: Cuentanos tu mejor chiste!!
21 Octubre 2011, 01:29 AM
Aqui os dejo una serie de chistes de humor negro:

El humor negro es como las piernas, algunos lo tienen y otros no.

Que es mas divertido que un niño muerto disfrazado de payaso metido en un contenedor?
Un niño muerto, disfrazado de payaso, metido en dos contenedores.

Que es mas divertido que un camion lleno de niños muertos disfrazados de payaso?
Un camion lleno de niños muertos disfrazados de payaso y uno vivo intentando salir.

Que es una persona oliendo el gas de un mechero?
Un judio nostalgico.

Que es un judio encima de un monton de ceniza.
Una reunion familiar.

En que se parece Miguel Angel Blanco a los delfines?
En que ambos tienen un agujero en la nuca.

Que es lo malo de que los Reyes Magos se follen a tu hermana?
Que son tus padres.

Mama, mama, porque han venido los Reyes Magos en agosto?
Hijo mio, con el cancer que tienes, te crees que llegas a enero?

- Pedrito, que te han regalado los reyes estas navidades?
- Un ordenador, una Play 3, la XBox, la Wii, la Nintendo DS, 30 juegos para cada consola, un mecano, todos los pokemon de peluche, tambien los digimon, la serie entera de Bola de Dragon, un kimono, la careta de goku... y a ti?
- A mi un triciclo de madera, pero es que no tengo cancer.

-Doctor, que es lo que tengo?
- Usted tiene cancer y altzeimer.
- Bueno, por lo menos no tengo cancer.

- Paco! Como llevas que tu hijo tenga SIDA?
- Con queso en lonchas.
- Queso en lonchas????
- Si. Es lo unico que me cabe por debajo de la puerta de su habitacion.

-Maria!!! Que me bajo al bar a tomar unos vinos.
- Vale, pero pegame ahora que luego me desvelas.

- Mama, puedo tirarme un pedo como el de ayer?
- NOOOOOOOO, HASTA QUE NO SE TE CUREN LOS PUNTOS NOOOOOOO!!!!

Alguno mas me se, pero ahora no me acuerdo...

¡¡¡¡Que los disfruteis!!!!
#855
¡Buenas!

La respuesta a tu pregunta esta en la estructura de las cadenas de caracteres en C. Si miras las codiciones que tiene que cumplir un vector de caracteres para considerarse cadena, sabras como truncar la cadena que te den en la posicion que quieras.

Resumiendo, investiga sobre lo que es una cadena de caracteres en C.

¡Saludos!
#856
¡Buenas!

Me trago mis palabras sin aliñar.  :silbar:

Acabo de probar la asignacion sin cast del puntero devuelto por malloc (utilizando el compilador de C) y no ha protestado ni me ha insultado ni nada.  :xD

Por lo que se ve en algun momento he debido de tener algun trauma con la conversion, seguramente porque cuando empece no me fijaba si creaba ficheros .c o .cpp, y lo deberia de hacer en .cpp por lo que me saltaba g++ en lugar de gcc... asi que desde entonces tengo la costumbre de hacer siempre el cast.

Siento haber mareado la perdiz de esta forma.

¡Saludos!
#857
Cita de: rir3760 en 15 Octubre 2011, 19:05 PM
Los prototipos de las funciones malloc, calloc, realloc y free se encuentran en el encabezado <stdlib.h>.

Cierto, no me habia dado cuenta de que le habia dicho que estaban en stdio  :P

Cita de: rir3760 en 15 Octubre 2011, 19:05 PM
Sobre la conversión explicita del "void *" que retornan esas funciones es obligatoria en C++ pero no se recomienda en C (ya que ella es automática)

Llevo mas de diez años programando en C, y nunca me ha dejado asignar directamente el puntero devuelto al asignar memoria dinamicamente. Siempre he utilizado MinGW (gcc, vamos), no se si otros compiladores permiten la asignacion directa o no, no los he usado y por lo tanto no lo puedo saber. Al reves de lo que dices, en C++ no hace falta realizar el cast, ya que el propio new devuelve un puntero correcto (o deberia hacerlo), del tipo de la clase (o vector de clases) que estes creando.

¡Saludos!
#858
¡buenas!

Todas malloc y realloc devuelven un puntero a void (void*), por lo tanto tendras que aplicarles un cast al tipo que quieras:

tu_tipo *un_puntero = NULL;

un_puntero = (tu_tipo*) malloc(sizeof(tu_tipo) * numero_de_componentes_que_quieras);


y lo mismo con realloc:

tu_tipo *un_puntero = NULL;

un_puntero = (tu_tipo*) realloc(un_puntero, sizeof(tu_tipo) * numero_de_componentes_que_quieras);


Recuerda que es mas que reconmendable inicializar los punteros a NULL. Si un_puntero es NULL, realloc actua como malloc, y si el segundo parametro de realloc es cero, actuara como free. Si el puntero que recibe realloc no ha sido asignado de forma dinamica (malloc o calloc) obtendras errores por violaciones de acceso, lo mismo que pasara con free.

Despues de intentar asignar memoria, comprueba siempre si se ha podido realizar la operacion (si el puntero devuelto es NULL o no). Si utilizas realloc, utiliza un puntero auxiliar para comprobar si se ha podido reasignar la memoria. Si lo haces sobre el mismo puntero que contiene los datos y se le asigna un valor a NULL por no poder haber conseguido redimensionar el vector, habras cometido dos errores, perder los datos en alguna parte de la memoria y no poder liberarla, dejandola de forma permanente ocupando un espacio de memoria. Por esto ultimo, debes acordarte siempre de liberar la memoria que asignes de forma dinamica.

¡Saludos!
#859
Tarde, pero me uno al velatorio.


#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Adios mundo.\n");
    return 0;
}
#860
¡Buenas!

Investiga sobre las funciones malloc, realloc y free (se encuentran en stdio.h). Son las que estas buscando.

Si te surgen dudas sobre su manejo, ya lo sabes, consultanos.

¡Saludos!