c - fread 给出空结果并检测到 glibc

标签 c

我想读取一个 txt/dat 文件,我正在使用以下代码,但它不会加载该文件,因为它会为每个指针打印零值。

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

int main( int argc, const char* argv[] ){

    const int N = 10;
    double *t = (double*) malloc ( N * sizeof(double) ); 
    double *x = (double*) malloc ( N * sizeof(double) );
    double *v = (double*) malloc ( N * sizeof(double) );

    FILE * theFile;
    theFile = fopen( "testFile.dat", "w" );
    assert( NULL != theFile );

    printf("\n BEFORE \n");
    for ( int i = 0; i < N; i++ ) 
    {   

        t[ i ] = i;
        x[ i ] = i + 1;
        v[ i ] = i * 2;

        // write result to file
        fprintf ( theFile, "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );        

        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

    }

    fclose( theFile );

    // open file for reading
    theFile = fopen( "testFile.dat", "r" );
    assert( NULL != theFile );

    const int buffSize = 3;
    double buffer[ buffSize ];

    fread( buffer, buffSize , N , theFile );

    t = &buffer[ 0 ];
    x = &buffer[ 1 ];
    v = &buffer[ 2 ];

    printf("\n AFTER \n");
    for ( int i = 0; i < N; i++ )
        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ],x[ i ],v[ i ] );

    fclose( theFile );

    free ( t );
    free ( x );
    free ( v );


return 0;

}

此外,如果我们有不同的数据类型,例如 2 个 double 和 1 个整数,我会使用 2 个不同的缓冲区并调用 fread 2 次吗?

最佳答案

要读回值,您应该将每一行作为字符串读取并解析它以提取浮点值,这是您的代码,已修复

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

int main( int argc, const char* argv[] ){

    const int N = 10;
    double *t = malloc ( N * sizeof(double) );
    double *x = malloc ( N * sizeof(double) );
    double *v = malloc ( N * sizeof(double) );

    FILE * theFile;

    theFile = fopen( "testFile.dat", "w" );
    assert( NULL != theFile );

    printf("\n BEFORE \n");
    for ( int i = 0; i < N; i++ )
    {

        t[ i ] = i;
        x[ i ] = i + 1;
        v[ i ] = i * 2;

        // write result to file
        fprintf ( theFile, "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

    }

    fclose( theFile );

    // open file for reading
    theFile = fopen( "testFile.dat", "r" );
    assert( NULL != theFile );

    int i = 0;
    while (fscanf(theFile, "%f%f%f", &(t[i]), &(x[i]), &(v[i])) == 3) i++;

    printf("\n AFTER \n");
    for ( int i = 0; i < N ; i++ )
        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ],x[ i ],v[ i ] );

    fclose( theFile );

    free ( t );
    free ( x );
    free ( v );


    return 0;
}

您的原始代码声明了一个大小为 3 的数组,并将指针 t xv 重新赋给指向数组,在下面的 for 中有问题,调用 free 将尝试 free 数组而不是原来的 malloced 指针。

如果你不需要以人类可读的格式存储数据,那么你可以使用这个

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

int main( int argc, const char* argv[] ){

    const int N = 10;
    double *t = malloc ( N * sizeof(double) );
    double *x = malloc ( N * sizeof(double) );
    double *v = malloc ( N * sizeof(double) );

    FILE * theFile;

    theFile = fopen( "testFile.dat", "w" );
    assert( NULL != theFile );

    printf("\n BEFORE \n");
    for ( int i = 0; i < N; i++ )
    {

        t[ i ] = i;
        x[ i ] = i + 1;
        v[ i ] = i * 2;

        // write result to file
        //fprintf ( theFile, "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

    }
    fwrite(t, sizeof(double), N, theFile);
    fwrite(x, sizeof(double), N, theFile);
    fwrite(v, sizeof(double), N, theFile);

    fclose( theFile );

    // open file for reading
    theFile = fopen( "testFile.dat", "r" );
    assert( NULL != theFile );

    fread(t, sizeof(double), N, theFile);
    fread(x, sizeof(double), N, theFile);
    fread(v, sizeof(double), N, theFile);

    printf("\n AFTER \n");
    for ( int i = 0; i < N ; i++ )
        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ],x[ i ],v[ i ] );

    fclose( theFile );

    free ( t );
    free ( x );
    free ( v );


    return 0;
}

最后要注意的是,始终检查malloc 的返回值,如果失败,它将返回NULL,表明您的系统内存不足,如果如果您不检查它,它返回了 NULL,您将在第一次尝试访问它时遇到段错误。

即使此代码有效,它也存在严重的不良实践问题我修复了代码以使其更健壮

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

int main( int argc, const char* argv[] ){

    const int N = 10;
    FILE *theFile = NULL;
    double *t = NULL;
    double *x = NULL;
    double *v = NULL;
    int errorCode = 0;

    t = malloc ( N * sizeof(double) );
    if (t == NULL)
        goto abort;
    x = malloc ( N * sizeof(double) );
    if (x == NULL)
        goto abort;
    v = malloc ( N * sizeof(double) );
    if (v == NULL)
        goto abort;

    theFile = fopen( "testFile.dat", "w" );
    if (theFile == NULL)
        goto abort;
    printf("\n BEFORE \n");
    for ( int i = 0; i < N; i++ )
    {

        t[ i ] = i;
        x[ i ] = i + 1;
        v[ i ] = i * 2;

        // write result to file
        fprintf ( theFile, "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ], x[ i ], v[ i ] );

    }
    fclose( theFile );

    // open file for reading
    theFile = fopen( "testFile.dat", "r" );
    if (theFile == NULL)
        goto abort;

    int i = 0;
    while (i < N) /* stop when you have read enough lines to fit t, x and v */
    {
        if (fscanf(theFile, "%f%f%f", &(t[i]), &(x[i]), &(v[i])) == 3)
        {
            /* This will not happen since you just created the file with the appropriate content
                * but the good practice here is to check for any problem during the read
                */
            errorCode = -1;

            printf("malformed line found in file.\n");
            goto abort;
        }
        i++;
    }

    printf("\n AFTER \n");
    for ( int i = 0; i < N ; i++ )
        printf( "%5.5f \t %5.5f \t %5.5f \n", t[ i ],x[ i ],v[ i ] );

abort: /* note: This prevents repeating the cleanup code */
    if (theFile != NULL)
        fclose( theFile );
    if (t != NULL)
        free ( t );
    if (x != NULL)
        free ( x );
    if (v != NULL)
        free ( v );

    return errorCode;
}

关于c - fread 给出空结果并检测到 glibc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27602535/

相关文章:

python - 通过 Python API 使用 C 库时遇到问题 : What am I doing wrong?

c - 数组值发生变化

c - C 中的性能/分析测量

c - while循环导致程序挂起

c - 递增字符数组指针

c - C 中使用回车符终止程序

c - 释放堆栈

c - PROCESS_EXTENDED_BASIC_INFORMATION 结构中标志的含义?

C - sscanf 不工作

c - 在c中声明没有任何数据类型的变量