PI-ITBA / 2024_01

7 stars 0 forks source link

tp7_ej5 #144

Closed matsdah closed 4 months ago

matsdah commented 6 months ago

Buenos dias, que tal? Queria preguntarles acerca de este ejercicio. Lo intenté plantear con punteros, la cosa es que no aborta con los asserts, pero termina con un codigo de salida basura. Intente hacerlo lo mas prolijo posible para que sea mas amena la correcion. A continuacion les muestro al compilacion con el flag fsanitizer y el codigo:


void separaCursos(const char * nombre[], const char * curso, char * cursoG, char * cursoH){
    int gIndex = 0, hIndex = 0;

    for(int i = 0; curso[i]; i++){      // Recorro el arreglo de cursos para asignarle a cada alumno G o H.
        switch (curso[i]) {
            case 'G':
                strcpy(cursoG + gIndex, *(nombre + i));
                gIndex++;
                break;

            case 'H':
                strcpy(cursoH + hIndex, *(nombre + i));
                hIndex++;
                break;

            default:
                puts("El arreglo Curso tiene datos incorrectos.");
                break;
        }
    }
    *(cursoH + hIndex) = '\0';
    *(cursoG + gIndex) = '\0';
    return;
}

Captura de pantalla 2024-04-29 110803

ImNotGone commented 6 months ago

pasa el programa entero pq te esta tirando segfault en main

matsdah commented 6 months ago

Te paso el codigo con el test:


#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX_ALUMNOS 4

typedef char * TAlumnos[MAX_ALUMNOS];
typedef char TCurso[];

void separaCursos(const char * nombre[], const char * curso, char * cursoG, char * cursoH);

int main(void){

    TAlumnos alumnos={"Juan", "Pedro", "Martin", ""}, cursoG, cursoH;
    TCurso curso={'H', 'G', 'H', 0};
    separaCursos(alumnos, curso, cursoG, cursoH);
    assert(!strcmp(cursoG[0], alumnos[1]));
    assert(!strcmp(cursoH[0], alumnos[0]));
    assert(!strcmp(cursoH[1], alumnos[2]));
    assert(!strcmp(cursoG[1], alumnos[3]) && !strcmp(cursoH[2], alumnos[3]));   // Terminan con ""

    alumnos[0]=""; curso[0]=0;  // Depende del tipo de alumnos, esta linea puede ser: "alumnos[0][0]=0; curso[0]=0;"
    separaCursos(alumnos, curso, cursoG, cursoH);
    assert(!strcmp(cursoG[0], alumnos[0]) && !strcmp(cursoH[0], alumnos[0]));

    puts("OK!");
    return 0;
}

void separaCursos(const char * nombre[], const char * curso, char * cursoG, char * cursoH){
    int gIndex = 0, hIndex = 0;

    for(int i = 0; curso[i]; i++){      // Recorro el arreglo de cursos para asignarle a cada alumno G o H.
        switch (curso[i]) {
            case 'G':
                strcpy(cursoG + gIndex, *(nombre + i));
                gIndex++;
                break;

            case 'H':
                strcpy(cursoH + hIndex, *(nombre + i));
                hIndex++;
                break;

            default:
                puts("El arreglo Curso tiene datos incorrectos.");
                break;
        }
    }
    *(cursoH + hIndex) = '\0';
    *(cursoG + gIndex) = '\0';
    return;
}
ImNotGone commented 6 months ago

cursoG y cursoH son char * en main y los estas tratando como char en separaCursos, fijate las warnings que te tira al compilar

matsdah commented 6 months ago

Ahi los castee en el main, sigue saltando segmentation fault al compilar de todas maneras.


#include <stdio.h>
#include <assert.h>
#include <string.h>
#define MAX_ALUMNOS 4

typedef char * TAlumnos[MAX_ALUMNOS];
typedef char TCurso[];

void separaCursos(const char * nombre[], const char * curso, char * cursoG, char * cursoH);

int main(void){

    TAlumnos alumnos={"Juan", "Pedro", "Martin", ""}, cursoG, cursoH;
    TCurso curso={'H', 'G', 'H', 0};
    separaCursos((const char **) alumnos, curso, (char *) cursoG, (char *) cursoH);
    assert(!strcmp(cursoG[0], alumnos[1]));
    assert(!strcmp(cursoH[0], alumnos[0]));
    assert(!strcmp(cursoH[1], alumnos[2]));
    assert(!strcmp(cursoG[1], alumnos[3]) && !strcmp(cursoH[2], alumnos[3]));   // Terminan con ""

    alumnos[0]=""; curso[0]=0;  // Depende del tipo de alumnos, esta linea puede ser: "alumnos[0][0]=0; curso[0]=0;"
    separaCursos((const char **) alumnos, curso, (char *) cursoG, (char *) cursoH);
    assert(!strcmp(cursoG[0], alumnos[0]) && !strcmp(cursoH[0], alumnos[0]));

    puts("OK!");
    return 0;
}

void separaCursos(const char * nombre[], const char * curso, char * cursoG, char * cursoH){
    int gIndex = 0, hIndex = 0;

    for(int i = 0; curso[i]; i++){      // Recorro el arreglo de cursos para asignarle a cada alumno G o H.
        switch (curso[i]) {
            case 'G':
                strcpy(cursoG + gIndex, *(nombre + i));
                gIndex++;
                break;

            case 'H':
                strcpy(cursoH + hIndex, *(nombre + i));
                hIndex++;
                break;

            default:
                puts("El arreglo Curso tiene datos incorrectos.");
                break;
        }
    }

    *(cursoH + hIndex) = '\0';
    *(cursoG + gIndex) = '\0';
}

Captura de pantalla 2024-04-29 112908

ImNotGone commented 6 months ago

Tenes que cambiar el prototipo de separa cursos, o el tipo de dato de cursoG / CursoH. Estas queriendo usar strcpy que copiaria caracter a caracter en el vector de cursoG, por lo que deberia ser char **. Si lo que queres hacer es igualar punteros, lo correcto NO es castear, es cambiar el tipo de dato de cursoG y CursoH, y NO usar strcpy.

ImNotGone commented 6 months ago

Castear no es lo correcto aca

matsdah commented 6 months ago

Ah okay, muchas gracias