-5

So I have this code that reads 2 files, organizes the data in structs and after is supposed to fill 2 other structs in the bottom function, however the code seems to not even start running the main function and I have no idea why.

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

typedef struct Curso {
    char Cod_inst[100];
    char Cod_curso[100];
    char Nome_inst[100];
    char Nome_curso[100];//este
    char Grau[100];
    int Vagas;
} Curso;

typedef struct Candidato {
    int StudentID;
    float ProvaIngresso;
    float NotaSecundario;
    float NotaCandidatura; // >10
    int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5;
    char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4]; //
} Candidato;

typedef struct Colocados {
    int StudentID;
    float NotaCandidatura;
    int Opcao;
    char Instituicao[100];
    char Curso[100];
} Colocados;

typedef struct NaoColocados {
    int StudentID;
    float NotaCandidatura;
} NaoColocados;

void LerCandidatos(Candidato *candidatos);

void LerFaculdades(Curso *cursos);

int ColocaOpcao1(Candidato *candidatos, Curso *cursos, Colocados *Colocado, NaoColocados *NaoColocado, int *flag1);

int main() {
    Candidato candidatos[60000];
    Curso cursos[5000];
    NaoColocados NaoColocado[60000];
    Colocados Colocado[60000];
    int flag1, flag2, flag3, flag4, flag5;

    LerFaculdades(&cursos);

    LerCandidatos(&candidatos);

    ColocaOpcao1(&candidatos, &cursos, &Colocado, &NaoColocado, &flag1);
    printf("%d", flag1);
    return 0;
}

void LerFaculdades(Curso *cursos) {
    FILE *fl;
    char linha[1000];
    char *tokencur;
    int linha_count = 0;
    int n = 0; //token pa controlar codigo intituição;

    // Open the CSV file for reading

    fl = fopen("Cursos_N05_V02.csv", "r");

    if (fl == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(linha, 1000, fl) != NULL) {

        if (linha_count > 0) {  // Skip the first line

            tokencur = strtok(linha, ",");
            strcpy(cursos[n].Cod_inst,tokencur);
            printf("\n%s", cursos[n].Cod_inst);

            tokencur = strtok(NULL, ",");
            strcpy(cursos[n].Cod_curso,tokencur);
            printf("\n%s", cursos[n].Cod_curso);

            tokencur = strtok(NULL, ",");
            strcpy(cursos[n].Nome_inst,tokencur);
            printf("\n%s", cursos[n].Nome_inst);

            tokencur = strtok(NULL, ",");
            strcpy(cursos[n].Nome_curso,tokencur);
            printf("\n%s", cursos[n].Nome_curso);

            tokencur = strtok(NULL, ",");
            strcpy(cursos[n].Grau,tokencur);
            printf("\n%s", cursos[n].Grau);

            tokencur = strtok(NULL, ",");
            cursos[n].Vagas = atoi(tokencur);
            printf("\n%d", cursos[n].Vagas);
            n++;
        }
        linha_count++;
    }
}

void LerCandidatos(Candidato *candidatos) {
    FILE *fp;
    char line[100];
    char *token;
    int line_count = 0;
    int i = 0; //token pa controlar numero do candidato;

    // Open the CSV file for reading
    fp = fopen("Candidatos_N10_C20_O05.csv", "r");

    if (fp == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(line, 100, fp) != NULL) {

        if (line_count > 0) {  // Skip the first line
            token = strtok(line, ",");
            candidatos[i].StudentID = atoi(token);
            printf("\n%d", candidatos[i].StudentID);

            token = strtok(NULL, ",");
            candidatos[i].ProvaIngresso = atof(token);
            printf("\n%f", candidatos[i].ProvaIngresso);

            token = strtok(NULL, ",");
            candidatos[i].NotaSecundario = atof(token);
            printf("\n%f", candidatos[i].NotaSecundario);

            token = strtok(NULL, ",");
            candidatos[i].NotaCandidatura = atof(token);
            printf("\n%f", candidatos[i].NotaCandidatura);

            token = strtok(NULL, ",");
            candidatos[i].Escolha1 = atoi(token);
            printf("\n%d", candidatos[i].Escolha1);

            token = strtok(NULL, ",");
            strcpy(candidatos[i].curso1,token);
            printf("\n%s", candidatos[i].curso1);

            token = strtok(NULL, ",");
            candidatos[i].Escolha2 = atoi(token);
            printf("\n%d", candidatos[i].Escolha2);

            token = strtok(NULL, ",");
            strcpy(candidatos[i].curso2,token);
            printf("\n%s", candidatos[i].curso2);

            token = strtok(NULL, ",");
            candidatos[i].Escolha3 = atoi(token);
            printf("\n%d", candidatos[i].Escolha3);

            token = strtok(NULL, ",");
            strcpy(candidatos[i].curso3,token);
            printf("\n%s", candidatos[i].curso3);

            token = strtok(NULL, ",");
            candidatos[i].Escolha4 = atoi(token);
            printf("\n%d", candidatos[i].Escolha4);

            token = strtok(NULL, ",");
            strcpy(candidatos[i].curso4,token);
            printf("\n%s", candidatos[i].curso4);

            token = strtok(NULL, ",");
            candidatos[i].Escolha5 = atoi(token);
            printf("\n%d", candidatos[i].Escolha5);

            token = strtok(NULL, ",");
            strcpy(candidatos[i].curso5,token);
            printf("\n%s", candidatos[i].curso5);
            i++;
        }
        line_count++;
    }
    fclose(fp);
}

int ColocaOpcao1(Candidato *candidatos, Curso *cursos, Colocados *Colocado, NaoColocados *NaoColocado, int *flag1) {

    for(int k = 0; k < 60000; k++ /*indicador dos candidatos*/) {
        for (int j = 0; j < 50000; j++) {
            if (candidatos[k].curso1 == cursos[j].Cod_curso && candidatos[k].NotaCandidatura >= 10) {//encontra um curso
                if (cursos[j].Vagas > 0) {
                    strcpy(Colocado[k].Curso, cursos[j].Nome_curso);
                    strcpy(Colocado[k].Instituicao, cursos[j].Nome_inst);
                    Colocado[k].NotaCandidatura = candidatos[k].NotaCandidatura;
                    Colocado[k].Opcao = 1;
                    Colocado[k].StudentID = candidatos[k].StudentID;
                    cursos[j].Vagas --;
                    *flag1 = 1;
                    return *flag1;
                }
                if (cursos[j].Vagas == 0) {
                    printf("hello");
                    *flag1 = 1;
                    return *flag1;
                }
            }
        }//nao encontra curso
        NaoColocado[k].NotaCandidatura = candidatos[k].NotaCandidatura;
        NaoColocado[k].StudentID = candidatos[k].StudentID;
        *flag1 = 0;
        return *flag1;
    }
}

I tried using test variables in several different places and figured out that while running the code doesn't even reach the main function.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Difrox
  • 19
  • 1
  • Try putting `printf` calls in several places to see where it's getting stuck. Or run your code in a debugger. – dbush Mar 11 '23 at 14:56
  • 2
    That's an awful lot of data you're allocating on the stack. You might want to move those big arrays to file-scope (i.e. not in a function). – pmacfarlane Mar 11 '23 at 15:00
  • 1
    I already [told you yesterday](https://stackoverflow.com/questions/75697652/my-code-isnt-running-all-the-way-till-the-end-what-can-i-do-to-change-that#comment133543517_75697652), that you allocate very much data on stack. Now you even added a ton more more data. That won't make it better. BTW: You are supposed to respond to feedback in comments. – Gerhardh Mar 11 '23 at 15:30
  • 1
    You also ignored all other comments. Still way too much code, still no checks for `NULL` pointer, no length check for `strcpy`. If you ignore all hints and continue to use broken code, what do you expect in the end? – Gerhardh Mar 11 '23 at 15:33
  • People would be less willing to help if you disregard their advice. What's the point if you're not going to listen? – Harith Mar 11 '23 at 15:48
  • hello , there is no reason to get angry at me. i m simpy someone who isnt very good at coding, your responces to my comments dont help me at all, it s like trying to tell someone with only first grade math that they need to use derivatives. I read a comment and spend 30 min trying to figure out what you guys are talking about, just to fail at understanding...being mean is not the way, i m sry if you get offended that i suck at this and cant get better or understand, but i just wanna get the project done. if you cant give propper advice pls stay quite. – Difrox Mar 11 '23 at 16:38
  • If you don't understand the comments, just ask what they mean. There is no point in making the project somehow run (or maybe just seem to run) while there are many defects that will bite your back the next time you are not looking... – Gerhardh Mar 11 '23 at 19:04
  • @Difrox no. It's like trying to teach differential calculus to someone who does not understand linear algebra - they do not understand any of the symbolic terms and representations. You seem to be, at least reasonable, at writing code, but with no understanding of the limitations of your environment. If you cannot manage things like null checks, some readers might suspect that you did not author the code you present. – Martin James Mar 12 '23 at 07:47

2 Answers2

0

Caveat: Not a total solution to your problem, but some code cleanups and simplifications that may help as I believe that the extra complexity of your code may be impeding your understanding.

Edit: I've added a second example with more cleanup.


[As others have mentioned], in main you have large arrays that are function scoped and placed on the stack. This can cause a stack overflow. The stack is a limited resource, so adding static will put them in global memory.


There is a lot of replicated code when reading in the .csv files. Replicated code is usually fixed with either subfunctions or macros.

In the functions that parse the .csv files, I've replaced the replicated code with macros: TOKGET_I, TOKGET_F, and TOKGET_S.


With an array of struct, an extra pointer can help. Instead of many (e.g.):

candidatos[k].curso1 == ...

We can do:

Candidato *cand = &candidatos[k];
cand->curso1 == ...

Whenever I see (e.g.):

int x1,x2,x3,x4,x5;

I want to use an array:

int x[5];

Here is the refactored code. I've compiled this, but not tested it. I used Google Translate on some of the variables so I could understand what they meant.

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

typedef struct Curso {
    char Cod_inst[100];
    char Cod_curso[100];
    char Nome_inst[100];
    char Nome_curso[100];               // este
    char Grau[100];
    int Vagas;
} Curso;

typedef struct Escolha {
    int Escolha;
    char curso[4];
} Escolha;

typedef struct Candidato {
    int StudentID;
    float ProvaIngresso;
    float NotaSecundario;
    float NotaCandidatura;              // >10

#if 0
    int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5;
    char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4];
#else
    Escolha Escolha[5];
#endif
} Candidato;

typedef struct Colocados {
    int StudentID;
    float NotaCandidatura;
    int Opcao;
    char Instituicao[100];
    char Curso[100];
} Colocados;

typedef struct NaoColocados {
    int StudentID;
    float NotaCandidatura;
} NaoColocados;

void LerCandidatos(Candidato *candidatos);
void LerFaculdades(Curso *cursos);
int ColocaOpcao1(Candidato *candidatos, Curso *cursos, Colocados *Colocado,
    NaoColocados *NaoColocado, int *flag1);

#define TOKGET_I(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        _ptr->_sym = atoi(tokcur); \
    } while (0)

#define TOKGET_F(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        _ptr->_sym = atof(tokcur); \
    } while (0)

#define TOKGET_S(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        strcpy(_ptr->_sym,tokcur); \
    } while (0)

int
main()
{
// NOTE/BUG: this is a lot of data to go on the stack -- adding static will
// put this in global memory
    static Candidato candidatos[60000];
    static Curso cursos[5000];
    static NaoColocados NaoColocado[60000];
    static Colocados Colocado[60000];
    int flag1, flag2, flag3, flag4, flag5;

    LerFaculdades(cursos);
    LerCandidatos(candidatos);

    ColocaOpcao1(candidatos, cursos, Colocado, NaoColocado, &flag1);
    printf("%d", flag1);

    return 0;
}

void
LerFaculdades(Curso *cursos)
{
    FILE *fl;
    char linha[1000];
    char *tokencur;
    int linha_count = 0;
    // token pa controlar codigo intituição;
    int n = 0;

    // Open the CSV file for reading
    fl = fopen("Cursos_N05_V02.csv", "r");
    if (fl == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(linha, 1000, fl) != NULL) {
        // Skip the first line
        if (linha_count > 0) {
            char *tokbuf = linha;
            Curso *curso = &cursos[n];

            TOKGET_S(curso,Cod_inst);
            TOKGET_S(curso,Cod_curso);
            TOKGET_S(curso,Nome_curso);
            TOKGET_S(curso,Grau);
            TOKGET_I(curso,Vagas);

            n++;
        }

        linha_count++;
    }
}

void
LerCandidatos(Candidato *candidatos)
{
    FILE *fp;
    char line[100];
    char *token;
    int line_count = 0;
    // token pa controlar numero do candidato;
    int i = 0;

    // Open the CSV file for reading
    fp = fopen("Candidatos_N10_C20_O05.csv", "r");
    if (fp == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(line, 100, fp) != NULL) {
        // Skip the first line
        if (line_count > 0) {
            Candidato *cand = &candidatos[i];
            char *tokbuf = line;

            TOKGET_I(cand,StudentID);
            TOKGET_F(cand,ProvaIngresso);
            TOKGET_F(cand,NotaSecundario);
            TOKGET_F(cand,NotaCandidatura);

            for (int j = 0;  j < 5;  ++j) {
                Escolha *choice = &cand->Escolha[j];
                TOKGET_I(choice,Escolha);
                TOKGET_S(choice,curso);
            }

            i++;
        }

        line_count++;
    }

    fclose(fp);
}

int
ColocaOpcao1(Candidato *candidatos, Curso *cursos, Colocados *Colocado,
NaoColocados *NaoColocado, int *flag1)
{
    // indicador dos candidatos

    for (int k = 0; k < 60000; k++) {
        Candidato *cand = &candidatos[k];
        Colocados *placed = &Colocado[k];
        NaoColocados *noplace = &NaoColocado[k];

        for (int j = 0; j < 50000; j++) {
            Curso *curso = &cursos[j];

            // encontra um curso
            Escolha *choice = &cand->Escolha[0];
            if (choice->curso == curso->Cod_curso &&
                cand->NotaCandidatura >= 10) {
                if (curso->Vagas > 0) {
                    strcpy(placed->Curso, curso->Nome_curso);
                    strcpy(placed->Instituicao, curso->Nome_inst);
                    placed->NotaCandidatura = cand->NotaCandidatura;
                    placed->Opcao = 1;
                    placed->StudentID = cand->StudentID;
                    curso->Vagas--;
                    *flag1 = 1;
                    return *flag1;
                }
                if (curso->Vagas == 0) {
                    printf("hello");
                    *flag1 = 1;
                    return *flag1;
                }
            }
            // nao encontra curso
        }

        noplace->NotaCandidatura = cand->NotaCandidatura;
        noplace->StudentID = cand->StudentID;

        *flag1 = 0;
        return *flag1;
    }
}

In the code above, I've used cpp conditionals to denote old vs. new code:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

Note: this can be cleaned up by running the file through unifdef -k


UPDATE:

A few more issues ...

You're using "magic numbers". That is, (e.g.) you have 60000 in several places. Better to use a #define:

#define NCAND       60000               // maximum number of students/candidates

Also, ColocaOpcao1 assumes that you have read in the maximum number of candidates and courses.

Better to have the functions that read the .csv files return the number that is actually read and have main pass those to ColocaOpcao1.

And, there is no check in the read functions for overflow of the given array.

You're using "ranked choice voting" to select which student is placed in which course. Although your code did read in all the given student's choices, ColocaOpcao1 only used the student's first choice.

So, we can change ColocaOpcao1 to try all of the student's choices, in order of most desired to least desired. This means an extra loop.

Here is the updated code. It has more annotation. Again, compiled but not tested:

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

#define NCHOICE     5                   // maximum number of choices
#define NCAND       60000               // maximum number of students/candidates
#define NCOURSE     5000                // maximum number of courses

typedef struct Curso {
    char Cod_inst[100];
    char Cod_curso[100];
    char Nome_inst[100];
    char Nome_curso[100];               // este
    char Grau[100];
    int Vagas;
} Curso;

typedef struct Escolha {
    int Escolha;
    char curso[4];
} Escolha;

typedef struct Candidato {
    int StudentID;
    float ProvaIngresso;
    float NotaSecundario;
    float NotaCandidatura;              // >10

#if 0
    int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5;
    char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4];
#else
    Escolha Escolha[NCHOICE];
#endif
} Candidato;

typedef struct Colocados {
    int StudentID;
    float NotaCandidatura;
    int Opcao;
    char Instituicao[100];
    char Curso[100];
} Colocados;

typedef struct NaoColocados {
    int StudentID;
    float NotaCandidatura;
} NaoColocados;

#if 0
void LerCandidatos(Candidato *candidatos);
void LerFaculdades(Curso *cursos);
#else
int LerCandidatos(Candidato *candidatos);
int LerFaculdades(Curso *cursos);
#endif

#if 0
int ColocaOpcao1(Candidato *candidatos, Curso *cursos, Colocados *Colocado,
    NaoColocados *NaoColocado, int *flag1);
#else
int ColocaOpcao1(int ncand,int ncourse,
    Candidato *candidatos, Curso *cursos, Colocados *Colocado,
    NaoColocados *NaoColocado, int *flag1);
#endif

#define TOKGET_I(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        _ptr->_sym = atoi(tokcur); \
    } while (0)

#define TOKGET_F(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        _ptr->_sym = atof(tokcur); \
    } while (0)

#define TOKGET_S(_ptr,_sym) \
    do { \
        char *tokcur = strtok(tokbuf,","); \
        tokbuf = NULL; \
        strcpy(_ptr->_sym,tokcur); \
    } while (0)

int
main()
{
// NOTE/BUG: this is a lot of data to go on the stack -- adding static will
// put this in global memory
    static Candidato candidatos[NCAND];
    static Curso cursos[NCOURSE];
    static NaoColocados NaoColocado[NCAND];
    static Colocados Colocado[NCAND];

// NOTE/BUG: flag2-flag5 are unused -- again, use an array?
#if 0
    int flag1, flag2, flag3, flag4, flag5;
#else
    int flags[5];
#endif

    int ncourse = LerFaculdades(cursos);
    int ncand = LerCandidatos(candidatos);

#if 0
    ColocaOpcao1(candidatos, cursos, Colocado, NaoColocado, &flag1);
    printf("%d", flag1);
#else
    ColocaOpcao1(ncand, ncourse,
        candidatos, cursos,
        Colocado, NaoColocado,
        flags);
    printf("%d\n", flags[0]);
#endif

    return 0;
}

int
LerFaculdades(Curso *cursos)
{
    FILE *fl;
    char linha[1000];
    int linha_count = 0;
    // token pa controlar codigo intituição;
    int n = 0;

    // Open the CSV file for reading
    fl = fopen("Cursos_N05_V02.csv", "r");
    if (fl == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(linha, 1000, fl) != NULL) {
        // check for overflow of array
        if (n >= NCOURSE) {
            printf("too many courses\n");
            exit(1);
        }

        // Skip the first line
        if (linha_count > 0) {
            char *tokbuf = linha;
            Curso *curso = &cursos[n];

            TOKGET_S(curso,Cod_inst);
            TOKGET_S(curso,Cod_curso);
            TOKGET_S(curso,Nome_curso);
            TOKGET_S(curso,Grau);
            TOKGET_I(curso,Vagas);

            n++;
        }

        linha_count++;
    }

#if 1
    fclose(fl);
#endif

    return n;
}

int
choicecmp(const void *vlhs,const void *vrhs)
{
    const Escolha *lhs = vlhs;
    const Escolha *rhs = vrhs;
    int cmp = rhs->Escolha - lhs->Escolha;
    return cmp;
}

int
LerCandidatos(Candidato *candidatos)
{
    FILE *fp;
    char line[100];
    int line_count = 0;
    // token pa controlar numero do candidato;
    int i = 0;

    // Open the CSV file for reading
    fp = fopen("Candidatos_N10_C20_O05.csv", "r");
    if (fp == NULL) {
        printf("Error: could not open file\n");
        exit(1);
    }

    // Read each line of the file and extract the string
    while (fgets(line, 100, fp) != NULL) {
        // check for overflow of array
        if (i >= NCAND) {
            printf("too many candidates\n");
            exit(1);
        }

        // Skip the first line
        if (line_count > 0) {
            Candidato *cand = &candidatos[i];
            char *tokbuf = line;

            TOKGET_I(cand,StudentID);
            TOKGET_F(cand,ProvaIngresso);
            TOKGET_F(cand,NotaSecundario);
            TOKGET_F(cand,NotaCandidatura);

            for (int ichoice = 0;  ichoice < NCHOICE;  ++ichoice) {
                Escolha *choice = &cand->Escolha[ichoice];
                TOKGET_I(choice,Escolha);
                TOKGET_S(choice,curso);
            }

            // sort candidate choices by desired rank
#if 1
            qsort(cand->Escolha,NCHOICE,sizeof(Escolha),choicecmp);
#endif

            i++;
        }

        line_count++;
    }

    fclose(fp);

#if 1
    return i;
#endif
}

int
ColocaOpcao1(int ncand, int ncourse,
    Candidato *candidatos, Curso *cursos, Colocados *Colocado,
    NaoColocados *NaoColocado, int *flag1)
{
    // indicador dos candidatos

    for (int k = 0; k < ncand; k++) {
        Candidato *cand = &candidatos[k];
        Colocados *placed = &Colocado[k];
        NaoColocados *noplace = &NaoColocado[k];

        for (int icourse = 0; icourse < ncourse; icourse++) {
            Curso *curso = &cursos[icourse];

            // encontra um curso
            for (int ichoice = 0;  ichoice < NCHOICE;  ++ichoice) {
                Escolha *choice = &cand->Escolha[ichoice];

                if (choice->curso == curso->Cod_curso &&
                    cand->NotaCandidatura >= 10) {
                    if (curso->Vagas > 0) {
                        strcpy(placed->Curso, curso->Nome_curso);
                        strcpy(placed->Instituicao, curso->Nome_inst);
                        placed->NotaCandidatura = cand->NotaCandidatura;
                        placed->Opcao = 1;
                        placed->StudentID = cand->StudentID;
                        curso->Vagas--;
                        *flag1 = 1;
                        return *flag1;
                    }

                    if (curso->Vagas == 0) {
                        printf("hello");
                        *flag1 = 1;
                        return *flag1;
                    }
                }
            }
            // nao encontra curso
        }

        noplace->NotaCandidatura = cand->NotaCandidatura;
        noplace->StudentID = cand->StudentID;

        *flag1 = 0;
        return *flag1;
    }

// NOTE/BUG: compiler doesn't know that this will never be reached and so it
// complains will full warnings enabled
#if 1
    *flag1 = 0;
    return *flag1;
#endif
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
0

The program does reach the main function, but the amount of memory defined in main with automatic storage (local variables and arrays) is huge and causes undefined behavior (an instance of Stack Overflow) which causes your program to finish immediately.

A quick fix for this problem it to define the arrays of structures as static, which will make them part of the data segment instead of the stack.

Note also these problems:

  • strtok is inappropriate to parse csv files because it considers any sequence of separator characters to be a single separator. Hence lines containing empty fields will be parsed incorrectly.

  • you do not test strtok return values, so you may have undefined behavior if the line has missing fields (which will be the case if it has empty fields)

  • you do not check the field length before copying strings with strcpy, causing potential buffer overflows on lines with long fields.

  • you do not support quoted field values.

Here is a modified version using ancillary functions with many more fixes (but still no support for quoted fields):

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

typedef struct Curso {
    char Cod_inst[100];
    char Cod_curso[100];
    char Nome_inst[100];
    char Nome_curso[100];//este
    char Grau[100];
    int Vagas;
} Curso;

typedef struct Candidato {
    int StudentID;
    float ProvaIngresso;
    float NotaSecundario;
    float NotaCandidatura; // >10
    int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5;
    char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4]; //
} Candidato;

typedef struct Colocados {
    int StudentID;
    float NotaCandidatura;
    int Opcao;
    char Instituicao[100];
    char Curso[100];
} Colocados;

typedef struct NaoColocados {
    int StudentID;
    float NotaCandidatura;
} NaoColocados;

int LerCandidatos(Candidato *candidatos, const char *filename);
int LerFaculdades(Curso *cursos, const char *filename);
int ColocaOpcao1(Candidato *candidatos, int num_candidatos,
                 Curso *cursos, int num_cursos,
                 Colocados *Colocado, int *num_Colocado,
                 NaoColocados *NaoColocado, int *num_NaoColocado);

enum {
    CSV_FIELD_OK = 0,
    CSV_FIELD_MISSING = 1 << 0,   // field missing (line had fewer fields)
    CSV_FIELD_TOO_LONG = 1 << 1,  // string field was truncated
    CSV_FIELD_EMPTY = 1 << 2,     // numeric field empty
    CSV_FIELD_EXTRA = 1 << 3,     // numeric field has extra characters
    CSV_FIELD_OVERFLOW = 1 << 4,  // numeric field out of range
};

int get_csv_string(const char **pp, char *dest, size_t size);
int get_csv_int(const char **pp, int *dest);
int get_csv_float(const char **pp, float *dest);

int main() {
    static Candidato candidatos[60000];
    static Curso cursos[5000];
    static NaoColocados NaoColocado[60000];
    static Colocados Colocado[60000];
    int num_cursos, num_candidatos, num_Colocado, num_NaoColocado;
    int flag1;

    num_cursos = LerFaculdades(cursos, "Cursos_N05_V02.csv");
    if (num_cursos < 0)
        return 1;

    num_candidatos = LerCandidatos(candidatos, "Candidatos_N10_C20_O05.csv");
    if (num_candidatos < 0)
        return 1;

    flag1 = ColocaOpcao1(candidatos, num_candidatos, cursos, num_cursos,
                         Colocado, &num_Colocado,
                         NaoColocado, &num_NaoColocado);
    printf("%d\n", flag1);
    return 0;
}

int get_csv_string(const char **pp, char *dest, size_t size) {
    const char *p = *pp;
    int res = CSV_FIELD_OK;
    if (*p == '\0' || *p == '\r' || *p == '\n') {
        res = CSV_FIELD_MISSING;
        if (size > 0)
            *dest = '\0';
    } else {
        size_t len = strcspn(p, ",\r\n");
        if (len < size) {
            memcpy(dest, p, len);
            dest[len] = '\0';
        } else {
            if (size > 0) {
                memcpy(dest, p, size - 1);
                dest[len] = '\0';
            }
            res |= CSV_FIELD_TOO_LONG;
        }
        *pp = p + len + (*p == ',');
    }
    return res;
}

int get_csv_int(const char **pp, int *dest) {
    const char *p = *pp;
    int res = CSV_FIELD_OK;
    long val;

    if (*p == '\0' || *p == '\r' || *p == '\n') {
        res = CSV_FIELD_MISSING;
        val = 0;
    } else {
        size_t len = strcspn(p, ",\r\n");
        char *end;
        errno = 0;
        val = strtol(p, &end, 10);
        if (val > INT_MAX) {
            val = INT_MAX;
            errno = ERANGE;
        } else
        if (val < INT_MIN) {
            val = INT_MIN;
            errno = ERANGE;
        }
        if (p == end) {
            res = CSV_FIELD_EMPTY;
        } else
        if (p + len != end) {
            res = CSV_FIELD_EXTRA;
        } else
        if (errno) {
            res = CSV_FIELD_OVERFLOW;
        }
        *pp = p + len + (*p == ',');
    }
    *dest = (int)val;
    return res;
}

int get_csv_float(const char **pp, float *dest) {
    const char *p = *pp;
    int res = CSV_FIELD_OK;
    float val;

    if (*p == '\0' || *p == '\r' || *p == '\n') {
        res = CSV_FIELD_MISSING;
        val = 0;
    } else {
        size_t len = strcspn(p, ",\r\n");
        char *end;
        errno = 0;
        val = strtof(p, &end);
        if (p == end) {
            res = CSV_FIELD_EMPTY;
        } else
        if (p + len != end) {
            res = CSV_FIELD_EXTRA;
        } else
        if (errno == ERANGE) {
            res = CSV_FIELD_OVERFLOW;
        }
        *pp = p + len + (*p == ',');
    }
    *dest = val;
    return res;
}

int LerFaculdades(Curso *cursos, const char *filename) {
    FILE *fp;
    char line[1000];
    int line_count = 0;
    int n = 0; //token pa controlar codigo intituição;

    // Open the CSV file for reading
    fp = fopen(filename, "r");
    if (fp == NULL) {
        fprintf(stderr, "Error: could not open file %s: %s\n",
                filename, strerror(errno));
        return -1;
    }

    // Skip the first line
    if (!fgets(line, sizeof line, fp)) {
        fprintf(stderr, "Invalid CSV file: %s\n", filename);
        fclose(fp);
        return -1;
    }

    // Read each line of the file and extract the string
    line_count = 1;
    while (fgets(line, sizeof line, fp) != NULL) {
        int status;
        const char *p = line;
        line_count++;
        status  = get_csv_string(&p, cursos[n].Cod_inst, sizeof(cursos[n].Cod_inst));
        status |= get_csv_string(&p, cursos[n].Cod_curso, sizeof(cursos[n].Cod_curso));
        status |= get_csv_string(&p, cursos[n].Nome_inst, sizeof(cursos[n].Nome_inst));
        status |= get_csv_string(&p, cursos[n].Nome_curso, sizeof(cursos[n].Nome_curso));
        status |= get_csv_string(&p, cursos[n].Grau, sizeof(cursos[n].Grau));
        status |= get_csv_int(&p, &cursos[n].Vagas);
        if (status || *p != '\n') {
            fprintf(stderr, "%s:%d: invalid csv line, status=%d: %s\n",
                    filename, line_count, status, line);
        }
        // Debug output
        printf("%s\n", cursos[n].Cod_inst);
        printf("%s\n", cursos[n].Cod_curso);
        printf("%s\n", cursos[n].Nome_inst);
        printf("%s\n", cursos[n].Nome_curso);
        printf("%s\n", cursos[n].Grau);
        printf("%d\n", cursos[n].Vagas);
        n++;
    }
    fclose(fp);
    return n;
}

int LerCandidatos(Candidato *candidatos, const char *filename) {
    FILE *fp;
    char line[1000];
    int line_count = 0;
    int n = 0;

    // Open the CSV file for reading
    fp = fopen(filename, "r");
    if (fp == NULL) {
        fprintf(stderr, "Error: could not open file %s: %s\n",
                filename, strerror(errno));
        return -1;
    }

    // Skip the first line
    if (!fgets(line, sizeof line, fp)) {
        fprintf(stderr, "Invalid CSV file: %s\n", filename);
        fclose(fp);
        return -1;
    }

    // Read each line of the file and extract the string
    line_count = 1;
    while (fgets(line, sizeof line, fp) != NULL) {
        int status;
        const char *p = line;
        line_count++;
        status  = get_csv_int(&p, &candidatos[n].StudentID);
        status |= get_csv_float(&p, &candidatos[n].ProvaIngresso);
        status |= get_csv_float(&p, &candidatos[n].NotaSecundario);
        status |= get_csv_float(&p, &candidatos[n].NotaCandidatura);
        status |= get_csv_int(&p, &candidatos[n].Escolha1);
        status |= get_csv_string(&p, candidatos[n].curso1, sizeof candidatos[n].curso1);
        status |= get_csv_int(&p, &candidatos[n].Escolha2);
        status |= get_csv_string(&p, candidatos[n].curso2, sizeof candidatos[n].curso2);
        status |= get_csv_int(&p, &candidatos[n].Escolha3);
        status |= get_csv_string(&p, candidatos[n].curso3, sizeof candidatos[n].curso3);
        status |= get_csv_int(&p, &candidatos[n].Escolha4);
        status |= get_csv_string(&p, candidatos[n].curso4, sizeof candidatos[n].curso4);
        status |= get_csv_int(&p, &candidatos[n].Escolha5);
        status |= get_csv_string(&p, candidatos[n].curso5, sizeof candidatos[n].curso5);
        if (status || *p != '\n') {
            fprintf(stderr, "%s:%d: invalid csv line, status=%d: %s\n",
                    filename, line_count, status, line);
        }
        // Debug output
        printf("%d\n", candidatos[n].StudentID);
        printf("%f\n", (double)candidatos[n].ProvaIngresso);
        printf("%f\n", (double)candidatos[n].NotaSecundario);
        printf("%f\n", (double)candidatos[n].NotaCandidatura);
        printf("%d\n", candidatos[n].Escolha1);
        printf("%s\n", candidatos[n].curso1);
        printf("%d\n", candidatos[n].Escolha2);
        printf("%s\n", candidatos[n].curso2);
        printf("%d\n", candidatos[n].Escolha3);
        printf("%s\n", candidatos[n].curso3);
        printf("%d\n", candidatos[n].Escolha4);
        printf("%s\n", candidatos[n].curso4);
        printf("%d\n", candidatos[n].Escolha5);
        printf("%s\n", candidatos[n].curso5);
        n++;
    }
    fclose(fp);
    return n;
}

int ColocaOpcao1(Candidato *candidatos, int num_candidatos,
                 Curso *cursos, int num_cursos,
                 Colocados *Colocado, int *num_Colocado,
                 NaoColocados *NaoColocado, int *num_NaoColocado)
{
    int j, k, k1 = 0, k2 = 0;
    int flag1 = 0;

    for (k = 0; k < num_candidatos; k++) {
        for (j = 0; j < num_cursos; j++) {
            if (candidatos[k].curso1 == cursos[j].Cod_curso
            &&  candidatos[k].NotaCandidatura >= 10) {
                //encontra um curso
                if (cursos[j].Vagas > 0) {
                    strcpy(Colocado[k1].Curso, cursos[j].Nome_curso);
                    strcpy(Colocado[k1].Instituicao, cursos[j].Nome_inst);
                    Colocado[k1].NotaCandidatura = candidatos[k].NotaCandidatura;
                    Colocado[k1].Opcao = 1;
                    Colocado[k1].StudentID = candidatos[k].StudentID;
                    k1++;
                    cursos[j].Vagas--;
                    flag1 = 1;
                    break;
                }
                if (cursos[j].Vagas == 0) {
                    printf("hello");
                    flag1 = 1;
                    break;
                }
            }
        }
        if (j == num_cursos) {
            //nao encontra curso
            NaoColocado[k2].NotaCandidatura = candidatos[k].NotaCandidatura;
            NaoColocado[k2].StudentID = candidatos[k].StudentID;
            k2++;
        }
    }
    *num_Colocado = k1;
    *num_NaoColocado = k2;
    return flag1;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189