读取值到双精度数组,读取的值与本地文件上的值不同。

huangapple go评论86阅读模式
英文:

C reading values into double array, read values are different from values on local file

问题

以下是您提供的代码部分的中文翻译:

我尝试将`txt`文件中的一列值读入C中的一个双精度数组(我多年没有写过C/C++了,将我视为一个新手)。文件中的值与双精度数组中的值不同。我不明白为什么以及如何更正它。

我还将C标准锁定为C99,因为我的C代码库的其他部分来自很久以前2006年)。但它们只在这些值被正确读取后才需要。

以下是执行此操作的代码片段:

#include <stdio.h>
#include <stdlib.h>

int main(){
    double *input = malloc(sizeof(double) * 30);
    FILE *fReader= fopen("../values.txt", "r");
    if (fReader == NULL){
        perror("出现以下错误:");
        return EXIT_FAILURE;
    }
    for(int i=0; i<30; i++){
    // 如果使用input[i]而不是(input+i),它会导致段错误。
        if(fscanf(fReader, "%f", (input+i)) != 1){
            perror("在读取值时出现以下错误:");
            fclose(fReader);
            return EXIT_FAILURE;
        }
        printf("当前值为%e \n", *(input+i));
    }

    if (ferror(fReader)){
        perror("读取后出现以下错误:");
        return EXIT_FAILURE;
    }
    if (fclose(fReader)){
        perror("关闭文件后出现以下错误:");
        return EXIT_FAILURE;
    }

    return 0;
}

请注意,这是您提供的代码的中文翻译,不包括问题中的其他内容。如果您有其他问题或需要进一步的帮助,请随时告诉我。

英文:

I've attempted to read a column of values in txt file into a double array in C (I haven't written C/C++ for years, take me as a newbie). The values in file and the values in the double array were different. I don't understand why and how to correct it.

I've locked C standard to C99 in CMAKE as well because other parts of my C codebase come from very old time (2006). But they are only after these values are correctly read.

Here's the code snippet to do so:

    #include &lt;stdio.h&gt;
    #include &lt;stdlib.h&gt;
    
    
    int main(){
        double *input = malloc(sizeof(double) * 30);
        FILE *fReader= fopen(&quot;../values.txt&quot;, &quot;r&quot;);
        if (fReader == NULL){
            perror(&quot;following error occurred:&quot;);
            return EXIT_FAILURE;
        }
        for(int i=0; i&lt;30; i++){
        // If I use input[i] instead, it&#39;s causing a segfault.
            if(fscanf(fReader, &quot;%f&quot;, (input+i)) != 1){
                perror(&quot;following error occurred during value reading: &quot;);
                fclose(fReader);
                return EXIT_FAILURE;
            }
            printf( &quot;%current value is %e \n&quot;, *(input+i));
        }
    
        if (ferror(fReader)){
            perror(&quot;following error occurred after reading: &quot;);
            return EXIT_FAILURE;
        }
        if (fclose(fReader)){
            perror(&quot;following error occurred closing file: &quot;);
            return EXIT_FAILURE;
        }
    
        return 0;
    }

This code ran ok, what's interesting was the values read in were different from the values on file.

Here's the output from gdb by doing p *input@30@1:

$1 = {
  {
    5.2090851696161347e-315,
    1.5708573496820653e-314,
    5.1267133989091838e-315,
    0,
    1.5717337030679671e-314,
    5.1214795787184985e-315,
    1.5632763856615201e-314,
    1.5698868046570466e-314,
    5.1603745953073066e-315,
    1.5776507290912971e-314,
    5.1890476209538565e-315,
    1.5757154067636091e-314,
    5.1701259393153366e-315,
    1.5646987621187767e-314,
    1.5706057487281833e-314,
    1.5745646547527293e-314,
    5.074800315787295e-315,
    1.5708606090331309e-314,
    1.5584251847289437e-314,
    5.0712624352138373e-315,
    1.5742053425473973e-314,
    5.121533268832232e-315,
    1.5713904213165801e-314,
    1.5767611663662882e-314,
    5.1426528410215284e-315,
    1.5729652822422439e-314,
    5.1593853918931727e-315,
    1.5747322610883588e-314,
    4.9742190195450526e-315,
    5.0023562211173747e-315
  }
}

And here's the file content (called values.txt):

0.421499729344799
-0.0637534886782198
0.106157122495887
0
-0.0769690171367188
0.0982644454758486
-0.0186078658644284
-0.0558087634241033
0.188837376753259
-0.207397239912854
0.300632085420638
-0.149027358129317
0.218247717844644
-0.0239702769714967
-0.0612296530370315
-0.119660179409031
0.0451857273951361
-0.0638026393400715
-0.00797183286147529
0.0425181372831318
-0.114241700013729
0.0983454129367622
-0.0717922840839158
-0.18056777523574
0.135388066712405
-0.0955414085415107
0.185853919257983
-0.122187706120336
0.00796167779508749
0.0132655904045542

答案1

得分: 1

&quot;%f&quot; in scanf() is for reading float. Use &quot;%lf&quot; (add l) instead for reading double.

You can use &amp;input[i] (not input[i] without &amp;) instead of (input+i) to read values.

Also note that the line

printf( &quot;%current value is %e \n&quot;, *(input+i));

invokes undefined behavior by

  • passing data having the wrong type to printf(): %c requests int, but *(input+i) has the type double.
  • not providing data corresponding to %e.
英文:

&quot;%f&quot; in scanf() is for reading float. Use &quot;%lf&quot; (add l) instead for reading double.

You can use &amp;input[i] (not input[i] without &amp;) instead of (input+i) to read values.

Also note that the line

printf( &quot;%current value is %e \n&quot;, *(input+i));

invokes undefined behavior by

  • passing data having wrong type to printf(): %c requests int, but *(input+i) has type double.
  • not providing data corresponding to %e.

答案2

得分: 1

OP的主要错误并不在于使用“不匹配的说明符和类型”,尽管这是其中的一个错误。

主要错误在于没有使用一个好的编译器,该编译器启用了所有警告。

警告: 格式'%f'需要'float *'类型的参数,但参数3的类型为'double *' [-Wformat=]
if (fscanf(fReader, "%f", (input + i)) != 1) {

警告: 格式'%c'需要'int'类型的参数,但参数2的类型为'double' [-Wformat=]
printf("当前值为%e \n", *(input + i));

警告: 格式'%e'需要匹配的'double'参数 [-Wformat=]
printf("当前值为%e \n", *(input + i));

节省自己(和其他人)的时间:启用所有编译器警告 @Eric Postpischil

启用良好的编译器具有最锐利的洞察力。

英文:

OP's key mistake is not about using a "mis-match specifier and type", although that is an error among others.

The major mistake: not using a good compiler was all warnings enabled.

warning: format &#39;%f&#39; expects argument of type &#39;float *&#39;, but argument 3 has type &#39;double *&#39; [-Wformat=]
if (fscanf(fReader, &quot;%f&quot;, (input + i)) != 1) {

warning: format &#39;%c&#39; expects argument of type &#39;int&#39;, but argument 2 has type &#39;double&#39; [-Wformat=]
printf(&quot;%current value is %e \n&quot;, *(input + i));

warning: format &#39;%e&#39; expects a matching &#39;double&#39; argument [-Wformat=]
printf(&quot;%current value is %e \n&quot;, *(input + i));

Save yourself (and others) time: Enable all compiler warnings @Eric Postpischil

Well enabled good compilers have the sharpest eyes.

huangapple
  • 本文由 发表于 2023年3月4日 02:37:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630728.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定