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 - MAFUS

#171
Creo que pregunta por los métodos.
#172
Programación C/C++ / Re: función en c
4 Enero 2019, 23:23 PM
Sobre lo que estás preguntando se llama guarda y es la condición por la cual debe terminar la recursividad. Si no existiera estaría entrando en la función hasta quedarse el programa sin memoria.

En las funciones hay dos formas de terminarlas:
1. Cuando llegan al final.
2. Cuando encuentran una sentencia return.

Lo que va a pasar cuando se llegue al final de la cadena es que la función va a regresar sin hacer nada dándole el control a la llamante.
Esa función continuará después de la llamada y escribirá el carácter, en este caso es el último de la cadena. Hecho esto llegará al final y le devolverá el control a su llamante.
Esa función, igual que la anterior, continuará después de la llamada escribiendo el carácter de la cadena, en su caso el penúltimo.
Las funciones irán escribiendo el carácter que les toca y devolviendo el control a su llamante hasta llegar a la primera que, una vez termine, continuará con la ejecución natural del programa.
#173
Para entender eso debes tener muy claro qué es una variable.

Una variable es una zona de memoria que alguien te ha dejado para que pongas cosas dentro. ¿Puedes cambiar esa zona de memoria? No, pero puedes cambiar lo que hay dentro.

Para verlo veamos un escalar, un int (4 bytes). Supongamos que el sistema te da la dirección 100 para tu variable, podrías hacer esto:
100: 0x00
101: 0x01
102: 0xFF
103: 0x00

Cómo puedes intuir el cambiar la dirección de los datos es absurdo, la memoria es la que es, es algo físico. Si acaso puedes copiar el contenido en otro sitio pero tienes que dar otro nombre a ese otro sitio para referenciarte a él.

Vayamos ahora a por los punteros, esas variables que contienen direcciones de memoria. Al igual que los escalares son variables y esto significa que están ancladas en una dirección de memoria. De la misma forma contienen números pero estos representan otras direcciones de memoria, y por contener direcciones de memoria tienen una aritmética especial; por lo demás son como escalares.

Las variables (escalares y punteros) devuelven su contenido, es decir: dónde C/C++ vea su nombre lo traducirá por su contenido.

Los arrays son una bestia extraña, una quimera. Un array es una ristra de elementos iguales contiguos. Supongamos un array de cuatro int y que éste empieza en la dirección de memoria 100:
100: 0x123847
104: 0x1038
108: 0x77483
112: 0x0

Cómo ves, al igual que los escalares cada elemento ocupa una dirección física que no se puede cambiar. Por tanto a un array no se le puede cambiar de dirección.
Pero a diferencia de los escalares están compuestos de muchos objetos, no sólo uno así que ¿cómo haces referencia a ellos? Para eso podrías hacer que el nombre del array devolviera su dirección de inicio y aplicar aritmética de punteros para referenciar a cada elemento. Así si tu array se llama miArray tendrías que:
miArray: devuelve 100 (igual que miArray+0)
miArray+1: devuelve 104 (recordar que un tipo entero son 4 bytes, aquí 100, 101, 102 y 103)
miArray+2: devuelve 108
miArray+3: devuelve 112

Y ya que tienen aritmética de punteros se dereferencian direcciones de memoria cómo los punteros:
*(miArray+2): devuelve 0x77483
En notación de array:
miArray[2]: devuelve 0x77483

Y esta es la razón por la que los índices de array empiezan por 0. Por otra parte y muy a tener en cuenta: el nombre del array devuelve su dirección de inicio.

Respondiendo a tu pregunta:
Ya has visto que los arrays devuelven su dirección por tanto cuándo pasas por parámetro un array lo que haces realmente es pasar su dirección así que no hay copia por valor de todo el array.

Pero la cosa se complica. ¿Qué ocurre cuándo pasas un array? Verás que el argumento del receptor debe dimensionar todas las dimensiones menos la primera. Algo así:
void miFuncion(int cubos[][100][100][100]);
El array recibe una colección de cubos.
¿Porqué la primera dimensión no está definida? Pues porque puede que tengas una colección de 1 de 100 o de 1000 cubos.
¿Y porqué las otras dimensiones sí están especificadas? C/C++ debe saber cuánto tiene que moverse por memoria cuándo des un índice. Por ejemplo:
La diferencia de memoria entre cubos[0] y cubos[1] es (1-0)*sizeof(int)*100*100*100.
La diferencia de memoria entre cubos[0][0][3][0] y cubos[0][0][5][0] es (5-3)*sizeof(int)*100.
#174
¿Por qué haces esto?

docentes=fopen("docentes.txt","ab+");
cargar(d);
fclose(docentes);


Por otra parte y cómo se ha repetido muchas veces: es un error cargar una estructura directamente a un archivo y recuperarla de él totalmente.
C/C++ puede mover los miembros de las estructuras y dejar espacios vacíos entre ellos para que se ajusten en la memoria. En algunas plataformas esto se soluciona serializando estos datos. Pero una forma rápida de resolverlo es grabando en disco miembro a miembro y a la hora de sacarlas leyendo miembro a miembro en el mismo orden.
Si no lo haces de esta forma puede que creas que estas leyendo legajo cuando en realidad estás leyendo nombre_apellidos, por ejemplo.


Me he tomado la libertad de hacerle algunos arreglillos, sobre todo para el tema de que el tamaño teórico de una estructura no es el real y alguna que otra cosa con el manejo de los archivos. Aún así necesita aun muchas mejoras: validar fechas, recibir el tipo de dato esperado desde la consola y toda una larga lista de etcéteras. También lo he pasado a C (C++ no me gusta).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_CADENA 50

typedef struct tfecha {
    int dia;
    int mes;
    int anyo;
} fecha;

typedef struct tformacion {
    char titulo[MAX_CADENA];
    char facultad[MAX_CADENA];
    char universidad[MAX_CADENA];
} formacion;

typedef struct tdocente {
    int legajo;
    char nombre_apellido[MAX_CADENA];
    fecha fecha_nac;
    formacion educacion;
    int DNI;
    char cargo[MAX_CADENA];
} docente;

void grabar_registro(docente *registro, FILE *archivo);
void leer_registro(docente *registro, FILE *archivo);
void cargar(docente *individuo);
void mostrar(docente *individuo);
void cargar_docentes(char * const nombre_archivo);
bool consulta(char * const nombre_archivo, int codigo);
void mostrar_docentes(char * const nombre_archivo);
void busqueda(char * const nombre_archivo, int codigo);
void modificar_docente(char * const nombre_archivo, int codigo);
void eliminar_docente(char * const nombre_archivo, int codigo);
void listar_docentes_especificos(char * const nombre_archivo, char * const buscado);
void nueva_cadena(char cadena[]);

int main() {
    char *docentes = "docentes.txt";
    int opcion, codigo;
    char buscado[MAX_CADENA];
    do {
        system("cls");
        puts("1. Cargar docente");
        puts("2. Consultar docente");
        puts("3. Listar docentes");
        puts("4. Buscar docente");
        puts("5. Modificar docente");
        puts("6. Eliminar docente");
        puts("7. Listar docentes por universidad");
        puts("8. Salir");
        printf("\n> ");
        scanf("%d", &opcion);
        switch(opcion) {
        case 1:
            cargar_docentes(docentes);
            break;
        case 2:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            if(consulta(docentes, codigo))
                puts("Docente encontrado");
            else
                puts("Docente no encontrado");
            break;
        case 3:
            mostrar_docentes(docentes);
            break;
        case 4:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            busqueda(docentes, codigo);
            break;
        case 5:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            modificar_docente(docentes, codigo);
            break;
        case 6:
            printf("Ingrese numero de legajo: ");
            scanf("%d", &codigo);
            eliminar_docente(docentes, codigo);
            break;
        case 7:
            printf("Ingrese universidad: ");
            nueva_cadena(buscado);
            listar_docentes_especificos(docentes, buscado);
            break;
        case 8:
            puts("FIN DEL PROGRAMA");
            break;
        default:
            puts("Opcion incorrecta");
        }
        system("pause");
    } while(opcion!=8);
}

void grabar_registro(docente *registro, FILE *archivo) {
    fwrite(&registro->legajo, sizeof(int), 1, archivo);
    fwrite(registro->nombre_apellido, sizeof(char), MAX_CADENA, archivo);
    fwrite(&registro->fecha_nac.dia, sizeof(int), 1, archivo);
    fwrite(&registro->fecha_nac.mes, sizeof(int), 1, archivo);
    fwrite(&registro->fecha_nac.anyo, sizeof(int), 1, archivo);
    fwrite(registro->educacion.titulo, sizeof(char), MAX_CADENA, archivo);
    fwrite(registro->educacion.facultad, sizeof(char), MAX_CADENA, archivo);
    fwrite(registro->educacion.universidad, sizeof(char), MAX_CADENA, archivo);
    fwrite(&registro->DNI, sizeof(int), 1, archivo);
    fwrite(registro->cargo, sizeof(char), MAX_CADENA, archivo);
}

void leer_registro(docente *registro, FILE *archivo) {
    fread(&registro->legajo, sizeof(int), 1, archivo);
    fread(registro->nombre_apellido, sizeof(char), MAX_CADENA, archivo);
    fread(&registro->fecha_nac.dia, sizeof(int), 1, archivo);
    fread(&registro->fecha_nac.mes, sizeof(int), 1, archivo);
    fread(&registro->fecha_nac.anyo, sizeof(int), 1, archivo);
    fread(registro->educacion.titulo, sizeof(char), MAX_CADENA, archivo);
    fread(registro->educacion.facultad, sizeof(char), MAX_CADENA, archivo);
    fread(registro->educacion.universidad, sizeof(char), MAX_CADENA, archivo);
    fread(&registro->DNI, sizeof(int), 1, archivo);
    fread(registro->cargo, sizeof(char), MAX_CADENA, archivo);
}

void cargar(docente *individuo) {
    puts("Ingrese datos del docente");
    printf("Legajo: ");
    scanf("%d", &individuo->legajo);
    printf("Nombre y apellido: ");
    nueva_cadena(individuo->nombre_apellido);
    puts("Fecha de nacimiento...");
    printf("Dia: ");
    scanf("%d", &individuo->fecha_nac.dia);
    printf("Mes: ");
    scanf("%d", &individuo->fecha_nac.mes);
    printf("Anyo: ");
    scanf("%d", &individuo->fecha_nac.anyo);
    puts("Formacion academica");
    printf("Titulo: ");
    nueva_cadena(individuo->educacion.titulo);
    printf("Facultad: ");
    nueva_cadena(individuo->educacion.facultad);
    printf("Universidad: ");
    nueva_cadena(individuo->educacion.universidad);
    printf("DNI: ");
    scanf("%d", &individuo->DNI);
    printf("Cargo: ");
    nueva_cadena(individuo->cargo);
}

void mostrar(docente *individuo) {
    puts("Datos del docente");
    printf("Legajo: %d\n", individuo->legajo);
    printf("Nombre y apellido: %s\n", individuo->nombre_apellido);
    printf("Fecha de nacimiento: %d/%d/%d\n", individuo->fecha_nac.dia, individuo->fecha_nac.mes, individuo->fecha_nac.anyo);
    puts("Formacion academica");
    printf("Titulo: %s\n", individuo->educacion.titulo);
    printf("Facultad: %s\n", individuo->educacion.facultad);
    printf("Universidad: %s\n", individuo->educacion.universidad);
    printf("DNI: %d\n", individuo->DNI);
    printf("Cargo: %s\n\n", individuo->cargo);
}

void cargar_docentes(char * const nombre_archivo) {
    docente d;
    FILE *fp;
    cargar(&d);
    if(consulta(nombre_archivo, d.legajo)==false) {
        fp=fopen(nombre_archivo, "ab");
        grabar_registro(&d, fp);
        fclose(fp);
    }
    else
        puts("El numero de legajo ya existe");
}

bool consulta(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo,"rb");
    if(fp) {
        c=fgetc(fp);
        while(!feof(fp) && !encontrado) {
            ungetc(c, fp);
            leer_registro(&d, fp);
            if(d.legajo==codigo)
                encontrado=true;
            c=fgetc(fp);
        }
    }
    fclose(fp);
    return encontrado;
}

void mostrar_docentes(char * const nombre_archivo) {
    docente d;
    char c;
    FILE *fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        mostrar(&d);
        c=fgetc(fp);
    }
    fclose(fp);
}

void busqueda(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp) && !encontrado) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(d.legajo==codigo) {
            mostrar(&d);
            encontrado=true;
        }
        c=fgetc(fp);
    }
    if(encontrado==false)
        puts("Docente no encontrado");
    fclose(fp);
}

void modificar_docente(char * const nombre_archivo, int codigo) {
    docente d;
    char c;
    long int posicion = 0;
    bool encontrado=false;
    FILE *fp=fopen(nombre_archivo, "rb+");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp) && !encontrado) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(codigo==d.legajo)
            encontrado=true;
        else
            posicion = ftell(fp);
        c=fgetc(fp);
    }
    if(encontrado) {
        ungetc(c, fp);
        cargar(&d);
        fseek(fp, posicion, SEEK_SET);
        grabar_registro(&d, fp);
    }
    else
        puts("Docente no encontrado");
    fclose(fp);
}

void eliminar_docente(char * const nombre_archivo, int codigo) {
    const char *nombre_temporal = "temporal.txt";
    docente d;
    char c;
    FILE *fp;
    FILE *temporal;
    fp=fopen(nombre_archivo, "rb");
    if(!fp) {
        printf("No se puede abrir el archivo %s\n", nombre_archivo);
        return;
    }
    temporal=fopen(nombre_temporal, "wb");
    if(!temporal) {
        puts("No se pudo generar el archivo temporal.");
        fclose(fp);
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(!feof(fp) && d.legajo!=codigo)
            grabar_registro(&d, temporal);
        c=fgetc(fp);
    }
    fclose(fp);
    fclose(temporal);
    if(remove(nombre_archivo)==0)
        rename(nombre_temporal, nombre_archivo);
    else
        puts("ERROR AL ELIMINAR");
}

void listar_docentes_especificos(char * const nombre_archivo, char * const buscado) {
    docente d;
    char c;
    FILE *fp = fopen(nombre_archivo, "rb");
    if(!fp) {
        puts("No se pudo abrir el archivo");
        return;
    }
    c=fgetc(fp);
    while(!feof(fp)) {
        ungetc(c, fp);
        leer_registro(&d, fp);
        if(strcmp(d.educacion.universidad, buscado)==0)
            mostrar(&d);
        c=fgetc(fp);
    }
    fclose(fp);
}

void nueva_cadena(char cadena[]) {
    char *c;
    fseek(stdin, 0, SEEK_END);
    fgets(cadena, MAX_CADENA, stdin);
    c = strchr(cadena, '\n');
    if(c)
        *c = '\0';
    fseek(stdin, 0, SEEK_END);
}
#175
Dónde dices for(y=0;y<12;y++)
  acu=acu+arr[x][y];

Debe decir y<11 porque sino también sumarán la propia suma.

Para la suma de las columnas es similar pero en vez de moverte primero por filas y dentro de ellas por columnas, primero debes moverte por columnas y dentro de ellas por filas.
#176
No es un  programa, es la definición de una clase para manejar una lista.
Lo que ves es un fallo del enlazador, le debe faltar algo para terminar de enlazar.
Por otra parte: la líne #include "list" parece que sobra. Se intenta incluir un archivo llamado list, que se encuentra en el mismo directorio que éste. Pero este se debe llamar list.h, así que creo que es un fallo intencionado que os ha introducido el profesor. Quien sabe.
#177
Puedo intuir qué es Racional, pero ¿Què es exactamente?
#178
Mete el valor en un double y castea uno de los operandos a double.
#179
Crea un array de dimensión conocida el cual tenga dos punteros: lectura, i y ecritura, o.
Genera dos únicas funciones que serán las que trabajaran con ese array: una de lectura y una de escritura.

Función de lectura:
Si el puntero o es igual al puntero i (las posiciones a las que apuntan) el buffer está vacío y deberás informar sobre ello; en caso contrario leerás el carácter que hay en la posición o y lo harás avanzar una posición. Si o queda fuera del array, o pasa a apuntar el principio del array. Devuelves el carácter leído.

La función de escritura:
Guardarás en la posición i el carácter conseguido y compruebas si en la siguiente posición está o. Si lo está avisar de ello, sino avanzar o a la siguiente posición. Por supuesto si la siguiente posición está fuera del array mover i al inicio del array.
#180
Intenta con cout << static_cast<void*>(&vocal);