C语言 我的代码没有一直运行到最后,我可以做些什么来改变它?

cpjpxq1n  于 2023-03-17  发布在  其他
关注(0)|答案(1)|浏览(87)

因此,我的代码应该读取一个文件并打印出读取的内容,同时将其组织成一个数据结构,然而代码在函数完成后停止运行。

#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)来试着找出哪里出了问题,但我找不出,程序根本不会在函数后面运行coed的行,我不明白为什么。

41zrol4v

41zrol4v1#

我知道我迟了两天才提出这项质询,而一些人已就解决方法发表意见,我在此提供一个答案和摘要,供大家参考。
所以我复制了你的代码,用调试器来检查。我创建了一个伪文件,用相同的列标题来测试。

问题

这是由Weather Vane识别的。您试图指向数组中不存在的索引。我注意到在将令牌变量赋给列值的行上。您将名为*restrict__s的参数设置为null。

token = strtok(NULL, ",");

解决方案

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

token = strtok(line, ",");

简而言之,代码是从一个空值中阅读一个,而你试图在转换的时候把这些空值赋给一个数组,所以对于空值的转换会失败,空值最终会被赋给数组。
这样就解决了问题。我让它打印出虚文件中的值,并打印出最终消息。
下面是代码应该如何查找您想要执行的操作。

法典

//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的对象Candidato似乎有点过分,它将在每次运行时为数组分配至少3,3Mb的内存。
4.如果我有更多的时间,我会尝试实现一个更好的方法来为Candidato对象赋值,而不是多次调用相同的3行,但公平地说,并不是所有的行都是相同的。我也会添加一些东西,在尝试为变量赋值之前检查null类型的值。

相关问题