我的代码没有一直运行到最后,我能做些什么来改变它?

问题描述 投票:0回答:1

所以我的代码应该读取一个文件并打印出读取的内容,同时将其组织成一个数据结构,但是代码在函数完成后就停止运行了。

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

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

void ColocaCandidatos(Candidato *candidatos);
int main() {


    Candidato candidatos[60000];

    ColocaCandidatos(&candidatos[60000]);

    int x = 1;
    int y = 2;
    int z = x +y;
    printf("%d",z);
  return 0;
}

void ColocaCandidatos(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++;
    }


}

我什至尝试使用测试变量(x,y,z)来尝试找出问题所在,但我无法弄清楚,该程序根本不在函数之后运行男女同校的行,我不明白为什么。

c function struct
1个回答
0
投票

我知道自问这个问题以来我迟到了两天,一些人已经评论了解决方案。如果有人需要,这里只是一个答案和摘要。

所以我复制了你的代码来用调试器检查。我创建了一个具有相同列标题的虚拟文件来进行测试。

问题

这是由 Weather Vane 确定的。您正试图指向数组中不存在的索引。我注意到在将令牌变量分配给列值的行中。您将名为 *restrict __s 的参数设置为 null。

token = strtok(NULL, ",");

解决方案

当它应该指向行变量时,像这样。

token = strtok(line, ",");

简而言之,代码是从 Null 值中读取 a ,并且您试图在转换这些 null 值时将它们分配给数组。因此,对于 Null 值,转换会失败,而 Null 值最终会分配给数组。

这解决了问题。我得到它来打印虚拟文件中的值并打印出最终消息。

这里是代码应该如何寻找你想做的事情。

守则

//The Header library files that the developer was using.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//* So this is a structure that the developer needs to use for his application.
typedef struct
{
    int StudentID;                                              // The Student's ID.
    float ProvaIngresso;                                        // TryIncome? Sorry I am using google translate.
    float NotaSecundario;                                       // Secondary Note.
    float NotaCandidatura;                                      // NoteCandidacy.
    int Escolha1, Escolha2, Escolha3, Escolha4, Escolha5;       // Pick1, Pick2, Pick3, Pick4, Pick5.
    char curso1[4], curso2[4], curso3[4], curso4[4], curso5[4]; // Cursor1, Cursor2, Cursor3, Cursor4, Cursor5.
} Candidato;

//* Here he declares a function with no body.
void ColocaCandidatos(Candidato candidatos[]);

//* The main entry point of the application.
int main()
{   
    Candidato candidatos[100];                                  // Here the struct object gets declared. 60000 seems a bit excessive? 

    ColocaCandidatos(candidatos);                               // Here the method is called.

    int x = 1;
    int y = 2;
    int z = x + y;
    printf("%d", z);                                            // I think this is a basic way of checking if the code ran to the end.

    return 0;                                                   // The application ends here.
}

//* This is the method that reads the file.
void ColocaCandidatos(Candidato candidatos[])
{
    // This is where the file handling is done.
    FILE *fp;                                                   // The FILE variable is declared.
    char line[100];                                             // An array with 101 available entries.
    char *token;                                                // A token. The asterisk indicates it will be for a memory cursor variable.
    int line_count = 0;                                         // How the user keeps track of what line he is on.
    int i = 0; // token pa controlar numero do candidato;       // Translation: token to control candidate number

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

    //If the FP variable is null, Then print an error saying the file could not be opened.
    if (fp == NULL)
    {
        printf("Error: could not open file\n");                 // This prints the message.
        exit(1);                                                // This exits with code 1, Meaning it will report it as an run with error's in the system logs.
    }

    // Read the lines of the file and extract the string as long as there is data in the file.
    while (fgets(line, 100, fp) != NULL)
    {
        if (line_count > 0) // Skip the first line
        { 
            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].StudentID = atoi(token);              //  This converts a string to an Integer and assigns it to Student ID variable of the Candidato structure.
            printf("\n%d", candidatos[i].StudentID);            //  This prints the Student's ID, Take note that its getting the value from the structure object. So it's a way of checking the output.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].ProvaIngresso = atof(token);          //  This converts a string to a float number and assign's it to the TryIncome variable.
            printf("\n%f", candidatos[i].ProvaIngresso);        //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].NotaSecundario = atof(token);         //  This converts a string to a float number and assign's it to the SecondaryNote variable.
            printf("\n%f", candidatos[i].NotaSecundario);       //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].NotaCandidatura = atof(token);        //  This converts a string to a float number and assign's it to the NoteCandidacy variable.
            printf("\n%f", candidatos[i].NotaCandidatura);      //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].Escolha1 = atoi(token);               //  This converts a string to a int number and assign's it to the Pick1 variable.
            printf("\n%d", candidatos[i].Escolha1);             //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            strcpy(candidatos[i].curso1, token);                //  This copies the value and assign's it to the cursor1 variable.
            printf("\n%s", candidatos[i].curso1);               //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].Escolha2 = atoi(token);               //  This converts a string to a int number and assign's it to the Pick2 variable.
            printf("\n%d", candidatos[i].Escolha2);             //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            strcpy(candidatos[i].curso2, token);                //  This converts a string to a float number and assign's it to the cursor2 variable.
            printf("\n%s", candidatos[i].curso2);               //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].Escolha3 = atoi(token);               //  This converts a string to a float number and assign's it to the Pick3 variable.
            printf("\n%d", candidatos[i].Escolha3);             //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            strcpy(candidatos[i].curso3, token);                //  This converts a string to a float number and assign's it to the cursor3 variable.
            printf("\n%s", candidatos[i].curso3);               //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].Escolha4 = atoi(token);               //  This converts a string to a float number and assign's it to the pick4 variable.
            printf("\n%d", candidatos[i].Escolha4);             //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            strcpy(candidatos[i].curso4, token);                //  This converts a string to a float number and assign's it to the cursor4 variable.
            printf("\n%s", candidatos[i].curso4);               //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            candidatos[i].Escolha5 = atoi(token);               //  This converts a string to a float number and assign's it to the Pick5 variable.
            printf("\n%d", candidatos[i].Escolha5);             //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            token = strtok(line, ",");                          //  This apparently divides strings into tokens seperated by character's.
            strcpy(candidatos[i].curso5, token);                //  This converts a string to a float number and assign's it to the cursor5 variable.
            printf("\n%s", candidatos[i].curso5);               //  This print's the variable's value from the object. It's a way of checking if a value assigned to the struct.

            i++;                                                //  Increment the loop integer.
        }

        line_count++;                                           //  Increment the line count.
    }

    fp = fclose(fp);                                            //  Close the reader, It's good practice ;).
}

我对代码和注释所做的其他更改

1.我更改了ColocaCandidatos的参数以使用普通对象数组。

2.我在函数结束时关闭阅读器,通常文件会在函数结束时关闭,但这是一个很好的做法。

3.用 60000 的数组大小声明候选对象似乎有点过分,每次运行时都会为数组分配至少 3.3Mb 的内存。

4.如果我有更多时间,我会尝试实现一种更好的方法来为 Candidato 对象分配值,而不是多次调用同一 3 行,但公平地说,并非所有行都是相同的。在尝试将值分配给变量之前,我还会添加一些检查空类型值的东西。

© www.soinside.com 2019 - 2024. All rights reserved.