当前位置: 首页 > 知识库问答 >
问题:

退出while循环时,fscanf失败

巴帅
2023-03-14

编辑:该问题与fscanf的while循环没有直接关系,而是在用于包含使用fscanf加载的变量的结构的分配中出现了错误

我正在从文件中读取值,并使用它们在使用fscanf的结构中设置参数。我使用Eclipse作为编辑器,并将其调试和gcc作为编译器(从Eclipse内部)。

我下面介绍的由三部分组成:1)我从文件中读入变量的结构的声明。2)我正在读取的文件,以及3)实际从文件中读取的代码。

在所有这些之下,有一个问题,不幸的是,这是一个相当具体的问题。但我越来越绝望了。

1)我正在阅读的结构声明如下:

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) 我正在读取的文件是以下.txt文件

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)以下函数将文件中的值读入结构如下:

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;
}

函数调用如下所示:

char SimuParamFileName[50]; 

sprintf(SimuParamFileName,"SimuParam_solidification.txt");


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

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

问题在于,当 fscanf 读取字符串“TConvec”时,它会将读取值放入它应该读取的变量中,但随后退出 while 循环,即使尚未到达文件的末尾。我可以在包含 TConvec 的输入文件中的行周围移动,并且 while 循环在到达 TConvec 时仍然终止。

如果我将输入文件的TConvec部分放在文件末尾,调试器将在以下位置结束

/* 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)

在弗夫斯坎夫。

当注释掉与TConvec相关的部分时,while循环以fscanf:

_IO_acquire_lock_clear_flags2(流);

我看不到

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

与其他“其他如果”语句有很大不同,这里也可能有多个错误。非常感谢对此的任何帮助或想法!

共有2个答案

曾嘉言
2023-03-14

正如@Strigidis在评论中指出的那样,我分配了错误使用的结构:

< code > struct StSimuParam * pStSimuParam = malloc(sizeof(struct STBC data));

应该是

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

不知何故,这导致了fscanf期间的错误。虽然我不确定为什么会这样...

酆乐湛
2023-03-14

我想我找到了问题所在,我的朋友。

听着,你的功能:

char str1[50];//用于与结构元素关键字进行比较的字符串

你的声明很好,但在你的代码中我发现了问题:

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

如我所见,您的str1和str2都与==2进行了比较,并且您没有使用strlen来过滤字符串中的空字符。如果您尝试过,也许会解决问题。

另一点可能是你的%*[^\n],当你比较时,这种格式可能会给str1和str2带来麻烦。

我希望能对这些提示有所帮助。如果可能,请回答我:您使用什么操作系统和复印机?它只是来自eclipse的GCC?

 类似资料:
  • 问题内容: 在下面的代码中,我希望循环在+ + =时立即退出。但是,使用语句进行测试表明它一直持续到循环完成为止。我尝试过,然后在语句集中进行设置,但这会导致无限循环。我认为使用然后设置可能有效,但也可以一直运行到循环结束为止。什么是最优雅,最快的退出方式?谢谢。 问题答案: 该循环将只匹配条件时,当控制返回到它,即循环完全执行。因此,这就是即使满足条件也不会立即退出程序的原因。 但是,如果条件没

  • 出现的问题是,当用户确实输入了一个正数时,它仍然忽略输入,并要求用户再次输入一个正整数。我想我只是没有正确退出循环,但我不确定是如何退出的。

  • 问题内容: 我正在尝试通过按键盘上的键来使while循环中断。我的代码是: 问题答案: 请勿使用循环获取输入,或。您真正想要的是一行输入,然后将其拆分为一个双打列表。因此,请使用,拆分并解析每个项目。像这样: 这忽略了任何形式的输入验证,但显示了一种通用方法。 这将起作用,因为一旦您单击“ enter”(输入),它将结束第一行,这意味着扫描程序可以越过进入代码的大部分。由于您再也不会尝试阅读任何内

  • //在下面的程序中,在内部,当用户收到指令时,他可以简单地进入哨兵退出while循环,但是,当您得到希望购买的票的结果时,按999并不退出程序

  • 问题内容: 在Java中退出/终止while循环的最佳方法是什么? 例如,我的代码当前如下: 问题答案: 用途: 但是,如果您的代码看起来 完全 像您指定的那样,则可以使用普通循环并将条件更改为:

  • 所以我这里有一个程序,它只是简单地模仿跳棋(但不是跳,而是一个棋子简单地“吃掉”另一个棋子)。我有一个简单的类,它实现了一个“checkers”类对象,并创建了一个名为“chips”的int数组变量。还有一个“while”语句,它在chip[0]和chips[1]整数大于0时创建了一个循环。看起来是这样的: Checkers类中的count方法如下所示: 板是8 x 8(这就是board.leng