-3

so... i am working in a hanoi towers program and this breaks the whole thing... may you help me please? This is my first question, and i don't really know how does this work :( it breaks when declaring "tablero" in the main function

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

void imprime(int *tab, int fil, int col, int ultNum, char name[64], char caso, int count, int filOrig, int filDest) {
    /*
    Precondición:
     *tab   Puntero a una matriz de tipo entero.
                                    fil     Entero que indica el numero de filas de la matriz.
                                    col     Entero que indica el numero de columnas de la matriz.
                                    disc    Parámetro de tipo entero que indica el numero de discos usados.
                                    ultNum  Entero que indica el numero que esta usando el disco mas grande.
     */FILE *f;
    switch (caso) {
        case 119:
            f = fopen(name, "w");
            break;
        case 97:
            f = fopen(name, "a");
            break;
        default:
            printf("no file");
            break;
    };
    int j, c;
    int i, esp;
    printf("Move %d to %d, movement number %d \n", filOrig, filDest, count);
    for (c = col - 1; c >= 0; c--) {
        for (j = 0; j < fil; j++) {
            esp = (ultNum - tab[col * j + c]) / 2;

            // Espacios a la izquierda
            for (i = 0; i < esp; i++) {

                fprintf(f, " ");

                printf(" ");
            };

            // Imprime los comodines
            for (i = 0; i < tab[col * j + c]; i++) {

                fprintf(f, "*");

                printf("*");
            };

            // Espacios a la derecha
            for (i = 0; i < esp; i++) {

                fprintf(f, " ");

                printf(" ");
            }

            fprintf(f, "\t");

            printf("\t");
        };

        fprintf(f, "\r\n");

        printf("\n");
    };


    printf("\n \n \n \n \n");

    fprintf(f, " \r\n \r\n \r\n \r\n \r\n ");

    fclose(f);
    count++;
};

void mueveDisco(int *tab, int fil, int col, int ultNum, int filOrig, int filDest, char name[64], char caso, int count) {
    /*
    Precondición:
     *tab   Puntero a una matriz de tipo entero.
                                    fil     Entero que indica el numero de filas de la matriz.
                                    col     Entero que indica el numero de columnas de la matriz.
                                    disc    Parámetro de tipo entero que indica el numero de discos usados.
                                    ultNum  Entero que indica el numero que esta usando el disco mas grande.
                                    filOrig Entero que indica el numero de fila de la matriz en la cual hay que coger el numero/disco
                                    filDest Entero que indica el numero de fila de la matriz en la cual hay que dejar el numero/disco.
    Poscondición:
                                    Se mueve el disco y se llama a la función que imprime el tablero.
     */

    int cO = col - 1, cD = col - 1;


    // Se busca el disco que se encuentre mas arriba y por lo tanto el mas pequeño de la fila de origen.
    while (cO >= 0 && tab[col * filOrig + cO] == 0) {
        cO--;
    };
    if (cO < 0)
        cO = 0;

    // Ahora se calcula cual es la posición libre mas arriba de la fila de destino
    while (cD >= 0 && tab[col * filDest + cD] == 0) {
        cD--;
    };

    // Se mueve el disco de la fila de origen a la de destino:
    tab[col * filDest + cD + 1] = tab[col * filOrig + cO];
    tab[col * filOrig + cO] = 0;

    // Se imprime el tablero:
    imprime(tab, fil, col, ultNum, name, caso, count, filOrig, filDest);
};

void hanoi(int *tab, int fil, int col, int disc, int ultNum, int O, int A, int D, char name[64], char caso, int count) {
    /*
    Precondición:
     *tab   Puntero a una matriz de tipo entero.
                                fil     Entero que indica el numero de filas de la matriz.
                                col     Entero que indica el numero de columnas de la matriz.
                                disc    Parámetro de tipo entero que indica el numero de discos usados.
                                ultNum  Entero que indica el numero que esta usando el disco mas grande.
                                O,A,D   Tres enteros que indican la fila desde donde se ha de coger el disco y a donde se ha de traspasar. La primera vez que se llama a hanoi tienen los valores de: 0 ,1 y 2 respectivamente.
    Poscondición:
                                Se llama recursivamente a hanoi hasta resolver el tablero.
     */

    if (disc == 1) {
        // Se borra la pantalla, se imprime la tabla y se hace una pausa que varia dependiendo del numero de discos:
        mueveDisco(tab, fil, col, ultNum, O, D, name, caso, count);
        if (col <= 5) system("sleep 0.8");
        else if (col <= 10) system("sleep 0.3");
        else if (col <= 15) system("sleep 0.06");
        else if (col > 15) system("sleep 0.02");
    } else {
        hanoi(tab, fil, col, disc - 1, ultNum, O, D, A, name, caso, count);
        mueveDisco(tab, fil, col, ultNum, O, D, name, caso, count);
        if (col <= 5) system("sleep 0.8");
        else if (col <= 10) system("sleep 0.3");
        else if (col <= 15) system("sleep 0.06");
        else if (col > 15) system("sleep 0.02");

        hanoi(tab, fil, col, disc - 1, ultNum, A, O, D, name, caso, count);
    };

};

int main(int argc, char *argv[]) {

    int k; /* Value for the "-q" optional argument. */

    time_t t = time(NULL);
    struct tm *tm = localtime(&t);
    char s[64];
    strftime(s, sizeof (s), "%c", tm);
    printf("%s\n", s);
    char name[64];
    int fil = 3, col = 3, *tablero = NULL;
    int j, c, disc = 1, ultNum;
    int count = 0;
    char caso;
    int i;

    /*
        printf("Escoja nombre del fichero :");
        scanf("%s", &name);
        printf( "Indique el numero de discos: " );
        scanf( "%i", &col );
        printf("Seleccione operacion en fichero: \n1. Añadir texto al archivo\n2. Reescribir archivo si existe\n3. No imprimir en archivo\n");
        scanf ("%d", &caso);
     */

    for (i = 0; i < argc; i++) {
        if (strcmp(argv[i], "-d") == 0) {
            col = atoi(argv[i + 1]);
        }
        if (strcmp(argv[i], "-f") == 0) {
            sprintf(name, "%s.txt", argv[i + 1]);
        }

        if (strcmp(argv[i], "-o") == 0) {
            caso = argv[i + 1];

        }
    }
    printf("hace el for\n");
    FILE *f;
    printf("hace el file\n");
    switch (caso) {
        case 119:
            f = fopen(name, "w");
            printf("escribí la w\n");
            break;
        case 97:
            f = fopen(name, "a");
            printf("escribi la a\n");
            break;
        default:
            printf("no file\n");
            break;
    };
    printf("hace el switch\n");
    tablero = (int *) malloc(sizeof (int)*fil * col); //peta aqui
    printf("hice el sizeof");
    // Resetea las torres poniendo "los discos" en una de ellas y 0 en el resto.
    for (j = 0; j < fil; j++)
        for (c = col - 1; c >= 0; c--)
            if (j == 0) {
                tablero[col * j + c] = disc;
                disc += 2;
            } else
                tablero[col * j + c] = 0;

    ultNum = disc;
    fprintf(f, " Comand line entered: \r\n Number of towers : %d \n\n Number of discs:  : %d \n\n Output filename   : %s \r\n \r\n Init time        : %s \r\n \r\n \r\n", fil, col, name, s);

    fclose(f);
    printf(" \n \n Comand line entered: \n Number of towers : %d \n Number of discs:    : %d \n Output filename : %s \n \n Init time        : %s \n \n \n", fil, col, name, s);

    // Se imprime el tablero antes de iniciar ningún movimiento:
    system("clear");
    imprime(tablero, fil, col, ultNum, name, caso, count, 0, 0);
    system("sleep 1");



    // Se llama a hanoi para comenzar "la partida":
    hanoi(tablero, fil, col, col, ultNum, 0, 1, 2, name, caso, count);
    f = fopen(name, "a");

    fprintf(f, " \r\n \r\n Fin Time : %s", s);

    fclose(f);
    return (0);
};
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • it's supposed to run from the command line, ./program.exe -d -f -o – Nacho -Marti Jun 17 '16 at 08:24
  • 4
    That [does not compile](http://cpp.sh/67cm). Please post a [mcve]. – Ken Y-N Jun 17 '16 at 08:29
  • Read up to `void imprime`, frowned, read further to `Puntero a una...`, stopped reading. I understand the urge to write your comments in your native language, but it severely reduces their usefulness in a context like this. Without a guide through your code that I could decipher without a translator, and seeing it's not "minimal" in the least (see Ken's comment), I am not willing to dig through this. Take that as constructive criticism. English comments preferred, and *isolate* those problems before posting. – DevSolar Jun 17 '16 at 09:10
  • 2
    In `caso = argv[i + 1];` warning "`char` differs in levels of indirection from `char *`". Also you did not `#include ` so the compiler's assumptions will be wrong. Please enable all warnings and take note of them. Also, don't use "magic numbers". `case 119:` --> `case 'w':` and `case 97:` --> `case 'a':` – Weather Vane Jun 17 '16 at 09:28

1 Answers1

1

It's very unclear what you mean, if it's a compilation error then that doesn't make sense connected to that particular line, since there are other errors that already prevent the code from building.

If it's a run-time error (it crashes when run), that makes no sense either since the code doesn't build.

A better way to write that particular line is:

tablero = malloc(fil * col * sizeof *tablero);

This

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606