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!