【问题标题】:Scanning numbers from a file line to line and stopping at some point (C)逐行扫描数字并在某个点停止 (C)
【发布时间】:2021-08-19 16:50:57
【问题描述】:

我有一个文件 (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

【问题讨论】:

  • 提示:当fscanf(Fdata,"%f %f %f %f \n", var_1, var_2, var_3, var_4);被调用时,传递给函数的指针var_1的值是多少?
  • 据我了解,var_1 的值是该行第一个数字的地址,对吧?
  • 马科斯科,不完全是。 var_1 传递的值进入 scanf() 是在函数调用之前 确定的。发布的代码在垃圾中传递,结果是 seg-fault。
  • 我明白了。所以我必须将变量的地址传递给scanf(),而不是传递随机指针,对吧?
  • Marcosko, Yas,正如检查过的答案所暗示的那样,传入已知float 的地址,因此scanf() 知道将其输入存储在哪里。顺便说一句,检查scanf() 的返回值以评估成功。

标签: c file segmentation-fault scanf


【解决方案1】:

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

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

问题在于您传递的指针“指向”内存中的随机地址。

所以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_2etc. 声明为 floats 而不是 指向浮点数的指针,您将需要更改另一行在您的代码中 - 涉及指针取消引用。 由于var_2_10 将不再是指针,因此取消引用它是没有意义的。

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

顺便说一句,具有局部范围的变量——如果没有显式初始化——将包含随机值。所以你的变量var_1var_2将指向随机地址。

【讨论】:

  • 就是这样,非常感谢。代码现在完美运行,我实际上学到了一些关于指针的东西。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 2012-06-09
    • 2016-09-28
    相关资源
    最近更新 更多