0
votes

EDIT: The problem had nothing directly to do with the while loop with fscanf but was an error in the allocation of the struct that is used to contain the variables loaded in using fscanf

I am reading values from a file and using them to set parameters in a struct using fscanf. I am using Eclipse as editor and for debugging and gcc as compiler (from within Eclipse).

What I present below consists of three parts: 1) A declaration of the struct that I am reading the variables from the file into. 2) The file that I am reading from and 3) The code that actually reads from the file.

Below all this comes by question, unfortunately a rather specific one. But I am getting desperate.

1) The struct that I am reading to is declared as follows:

struct StSimuParam{

    // Control parameters

    int HeatSource; // Kind of internal heat source? // 0: No internal heat source, 1: Constant internal heat source, 2: Varying internal heat source

    // Simulation parameters

    double TotTime;
    double dt;
    double CurrentTime;

    int TotIter; // Calculated as TotTime/dt
    double beta; // Weighting between forwards and backwards euler time scheme

    double TCastInit; // Initial casting temperature
    double TMouldInit; // Initial mould temperature

    // Physical parameters
    double Thickness; // Element thickness, constant for all elements
    double HeatCondNumber[3]; // Heat conduction number. Index 0: melt, index 1: solidified alloy, index 2: mould
    double Cp[3]; // Specific heat capacity. Index 0: melt, index 1: solidified alloy, index 2: mould
    double TConvec; // The temperature at infinity that controls the convection cooling
    double HeatTransfCoef; // Heat transfer coefficient.

    // Average density of element
    double *AvgRho;
    double *AvgCp;
    double *AvgHeatCondNumber;

    };

2) And the file that I am reading from is the following .txt file

Input for thermal solver. Need descriptions of all quantities  

Thickness           0.01    Thickness of elements  

HeatCondNumLiq      100     Heat conduction number for liquid  
HeatCondNumSol      100     Heat conduction number for solid alloy  
HeatCondNumMould    10      Heat conduction number for mould  

CpLiq               500     specific heat capacity of liquid  
CpSol               500     specific heat capacity of solid alloy  
CpMould             50      specific heat capacity of mould  
TCastInit           1260    Casting initial temperature  
TMouldInit          20      Mould initial temperature  

TConvec             500     Convective cooling temperature (T_infinity)  

dt                  0.01    Time step size  
TotTime             0.04    Total time  
beta                0.5     Parameter for the time stepping proceedure (0.5 : Crank - Nicholson)  

HeatTransfCoef      50000   Heat transfer coefficient between mould and convectively cooling airInput for thermal solver. Need descriptions of all quantities

3) The following function reads the values from the file into the struct is the following:

struct StSimuParam *set_simu_param(char *SimuParamFileName){

    struct StSimuParam *pStSimuParam =  malloc(sizeof(struct StBCData));

        FILE *fp;

        fp = fopen(SimuParamFileName,"r");

        if (fp == NULL){ // Check if file could be opened
                fprintf(stderr, "Can't open file %s!\n",SimuParamFileName);
                exit(EXIT_FAILURE);
        }



        char str1[50]; // string for comparison to struct element keywords
        char str2[20]; // string containing the value according to the keyword in str1

        while (fscanf(fp,"%s %s %*[^\n]",str1,str2) == 2){

            printf("str1: ");
            puts(str1);
            printf("str2: ");
            puts(str2);

            if (strcmp(str1,"Thickness") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->Thickness));
                printf("Thickness = %f\n",pStSimuParam->Thickness);
            }
            else if (strcmp(str1,"HeatCondNumLiq") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->HeatCondNumber[0]));
                printf("HeatCondNumber = %f\n",pStSimuParam->HeatCondNumber[0]);
            }
            else if (strcmp(str1,"HeatCondNumSol") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->HeatCondNumber[1]));
                printf("HeatCondNumber = %f\n",pStSimuParam->HeatCondNumber[1]);
            }

            else if (strcmp(str1,"HeatCondNumMould") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->HeatCondNumber[2]));
                printf("HeatCondNumber = %f\n",pStSimuParam->HeatCondNumber[2]);
            }

            else if (strcmp(str1,"CpLiq") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->Cp[0]));
                //printf("RhoCp = %f\n",pStSimuParam->RhoCp);
            }

            else if (strcmp(str1,"CpSol") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->Cp[1]));
                //printf("RhoCp = %f\n",pStSimuParam->RhoCp);
            }
            else if (strcmp(str1,"CpMould") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->Cp[2]));
                //printf("RhoCp = %f\n",pStSimuParam->RhoCp);
            }

            else if (strcmp(str1,"beta") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->beta));
                //printf("beta = %f\n",pStSimuParam->beta);
            }
            else if (strcmp(str1,"dt") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->dt));
                //printf("dt = %f\n",pStSimuParam->dt);
            }

            else if (strcmp(str1,"TotTime") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->TotTime));
                printf("TotTime = %f\n",pStSimuParam->TotTime);
            }

            else if (strcmp(str1,"HeatSource") == 0){
                sscanf(str2, "%d", &(pStSimuParam->HeatSource));
                //printf("HeatSource = %d\n",pStSimuParam->HeatSource);
            }

            else if (strcmp(str1,"TConvec") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->TConvec));
                printf("TConvec = %f\n",pStSimuParam->TConvec);
            }

            else if (strcmp(str1,"HeatTransfCoef") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->HeatTransfCoef));
                printf("HeatTransfCoef = %f\n",pStSimuParam->HeatTransfCoef);
            }

            else if (strcmp(str1,"TCastInit") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->TCastInit));
            }

            else if (strcmp(str1,"TMouldInit") == 0){
                sscanf(str2, "%lf", &(pStSimuParam->TMouldInit));
            }

        }
fclose(fp);

    return pStSimuParam;
}

The function call is the following:

char SimuParamFileName[50]; 

sprintf(SimuParamFileName,"SimuParam_solidification.txt");


/****** Set simulation parameters for thermal solver  **************/

struct StSimuParam *pStSimuParam;
pStSimuParam = set_simu_param(SimuParamFileName);

The problem is that when fscanf reads the string "TConvec", it puts the read value into the variable it should, but then exits the while-loop, even though the end of the file has not been reached. I can move arround the line in the input file containing TConvec, and still the while loop terminates when it reaches TConvec.

If I put the TConvec part of the input file to the end of the file, the debugger ends at

/* We add the additional test for EOF here since otherwise
inchar will restore the old errno value which might be
EINTR but does not indicate an interrupt since nothing
was read at this time.  */
    if (__builtin_expect ((c == EOF || inchar () == EOF)

in vfscanf.

When commenting out the part concerning TConvec, the while loop ends with a segmentation fault in this line in fscanf:

_IO_acquire_lock_clear_flags2 (stream);

I can't see that

else if (strcmp(str1,"TConvec") == 0){
    sscanf(str2, "%lf", &(pStSimuParam->TConvec));
    printf("TConvec = %f\n",pStSimuParam->TConvec);
}

is much different from the other "else if" statements, and there might also be multiple errors in play here. Any help or thoughts on this is much appreciated!

2
You will be better off running through a debugger and paying particular attention to pointers.unxnut
Quickly scanning, this code seems far from a minimal example…mafso
"struct StSimuParam *pStSimuParam = malloc(sizeof(struct StBCData));". Don't malloc your variable that way. Use "malloc(sizeof(struct StSimuParama))" instead.Strigidis
Your question needs to be trimmed down to only what is needed to solve the problem. The rest of it is fluff.Engineer2021
Sorry about the lengthy question. I definitely see your point. @Strigidis: Wow, that is embarrasing. Your comment solved my problem, thank you! Can anyone comment on why this would cause an error in fscanf?user1885353

2 Answers

0
votes

I Think that I found the problem my friend.

Look, Your function:

char str1[50]; // string for comparison to struct element keywords

It`s fine your declaration, but here in your code I ound the problem:

while (fscanf(fp,"%s %s %*[^\n]",str1,str2) == 2){

As i see, your str1 and str2, both r been comparated with ==2, and you didnt use a strlen to filter the null caracters from the string. If you tried maybe it`ll fix the problem.

Other point that can be is your %*[^\n] maybe this format is making trouble with the str1 and str2 when you compare.

I Hope be helpfull with this tips. If possible, answer me: What OS r u using and Copiler? its only the GCC from eclipse?

0
votes

As pointed out in a comment by @Strigidis, I was allocating the struct that I use wrongly:

struct StSimuParam *pStSimuParam = malloc(sizeof(struct StBCData));

should be

struct StSimuParam *pStSimuParam = malloc(sizeof(struct StSimuParama));

Somehow this caused the error during fscanf. Although I am not sure why this is the case...