从文件行到行扫描数字并在某个点停止 (C)

Scanning numbers from a file line to line and stopping at some point (C)

我有一个包含几行的文件 (input.dat),每行有 4 个数字。我想用 C 编写一个脚本来读取第 10 行的数字,我将其保存为 var_i_10(i=1,2,3,4)。然后,我希望它逐行检查,直到第二个数字比 var_2_10 低 5%。那时,我希望程序记下它在另一个文件 (output.dat) 上停止的行。

这是我想出的:

#include <stdio.h>


int main(void) {
    
    FILE *Fdata;  //The file with the data
    FILE *Foutput;  //The file I want to write the final result
    float *var_1, *var_2, *var_3, *var_4, *var_1_10, *var_2_10, *var_3_10, *var_4_10; //The variables in input.dat
    int i; //The line number
   
    Fdata=fopen("input.dat","r");
    Foutput = fopen("output.dat","w+");
    
    for (i = 0; i < 10; i++){
        
        fscanf(Fdata,"%f %f %f %f \n", var_1, var_2, var_3, var_4); //skip the first 50 lines
        
    }
    
    fscanf(Fdata, "%f %f %f %f \n", var_1_10, var_2_10, var_3_10, var_4_10); //save the numbers on line 10
    
    i = 10;
    
    
    while ((var_2_10 - var_2)<0.05*(*var_2_10)){ 
        
        fscanf(Fdata,"%f %f %f %f \n", var_1, var_2, var_3, var_4); //keep reading until var_2 is 5% lower than var_2_10
        
        i++;
        
    }
    
    fprintf(Foutput, "%d \n", i); //print the number o the last line read
    fclose(Foutput);
    
    return 0;
    
}

现在,脚本可以编译,但是当我尝试执行它时,它会出现“分段错误(核心已转储)”错误。有谁知道我做错了什么?我对C几乎一无所知,所以我的代码中可能有很多错误。

input.dat 文件如下所示:

1.8125 0.944824 7.43362e-05 7.88432e-06
1.74121 0.918457 4.73094e-05 0.000127544
1.69922 0.897949 6.00231e-05 2.91268e-05
1.7334 0.905762 0.000317385 7.81227e-05
1.70898 0.899902 0.000243394 2.10955e-05
1.72559 0.903809 9.5074e-05 0.000149768
1.71387 0.899414 0.000166243 0.000185066
1.68359 0.89209 0.00018385 0.000303927
1.68359 0.88623 0.000219556 0.000178714
1.70508 0.894531 0.000488326 0.000411066
1.69336 0.880859 0.000139567 0.000568174
1.70605 0.89209 0.000196065 0.000167238
1.69043 0.882324 5.66663e-05 0.00017306
1.67578 0.881836 0.00014178 0.000137113
1.67969 0.876465 0.000261803 2.60709e-05
1.67773 0.879883 0.000250439 8.21055e-05
1.71191 0.879395 0.000311615 0.000118544
1.68652 0.879883 0.00023477 0.000101067
1.68262 0.890625 0.000310484 8.81731e-05
1.70898 0.890137 0.000591565 3.71699e-05
1.70312 0.89502 0.000248289 7.57763e-05
1.71875 0.903809 0.000555975 4.18079e-05
1.71289 0.901367 0.000265478 3.96961e-05
1.69434 0.892578 5.50881e-05 0.00085942
1.68945 0.880371 0.000153156 0.0011145
1.66504 0.868164 0.000155594 0.000752835
1.65039 0.853027 0.000255484 0.00133279
1.6748 0.862793 0.000207765 0.00148763
1.66406 0.850586 0.00043458 0.00064662
1.63086 0.84082 0.00124341 0.000331652
1.66113 0.848145 0.00141408 0.00108942
1.64746 0.845215 0.000985863 0.000169982
1.65039 0.855957 0.000606564 0.000577116
1.65527 0.853027 0.000982811 0.000660586
1.63086 0.841309 0.000670502 0.00120878
1.64746 0.84668 0.000579282 0.000597114
1.67871 0.850586 0.000324774 0.00139627
1.63574 0.82959 0.000331599 0.00224275
1.61719 0.828125 0.000564358 0.00185258
1.66504 0.845215 0.000896463 0.00230424
1.64062 0.832031 0.000774724 0.00195404
1.62793 0.835449 0.000624469 0.00127606

chux 在上面的评论中为您提供了线索。

您似乎正确地意识到 - 对于整数占位符 - fscanf() 需要一个指向整数的指针(即它的地址)。

问题是您传递的指针 'pointing' 指向内存中的随机地址。

因此 fscanf() 尝试在解析时取消对无效指针的引用。 这会导致您提到的分段错误。

而不是

float *var_1, *var_2, *var_3, *var_4; // etc..

使用

float var_1, var_2, var_3, var_4; // etc.

并在您对 fscanf() 的调用中传递这些变量的 地址 (不是变量本身)。例如,而不是

fscanf(Fdata,"%f %f %f %f \n", var_1, var_2, var_3, var_4);

使用

fscanf(Fdata,"%f %f %f %f \n", &var_1, &var_2, &var_3, &var_4);

您需要为所有 fscanf() 次通话进行此更改。

您的程序还有一个问题。 一旦您将 var_1var_2 声明为 floats 而不是 指向浮点数的指针,您将需要更改代码中的另一行 - 涉及指针取消引用。 由于 var_2_10 将不再是指针,因此取消引用它没有意义。

您也许可以自己解决这个问题 - 罪魁祸首相当明显。

顺便说一句,具有局部作用域的变量 - 如果未明确初始化 - 将包含随机值。因此,您的变量 var_1var_2 将指向随机地址。

问题出在您的 fscanf() 上。你应该使用 fscanf(Fdata,"%f %f %f %f \n", &var_1, &var_2, &var_3, &var_4);。如果您正在处理文件,请始终检查文件是否已加载。下面的代码可以帮助您检查加载的文件,然后执行您的任务。Click here to get code