Ignacio Rey
Ignacio Rey

Reputation: 63

Error when I try to open a .dat file

I have a problem when I try to open a .dat file in a c code. Probably the error I made will be very obvious to some of you but I can't find it so I ask for your help. The point of my code is to open the .dat file which contains 12.000.000 double numbers and store it in a cuDoubleComplex array which size will be 6.000.000 variables (the even variables of the .dat represents the real part and the odd variables the imaginary (I mean the order, not the value of the variable))

Here is an extract of my code:

#include "cuComplex.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

int main(void)
{
    int n = 12000000; //12.000.000
    int lse = n / 2;
    double *data = (double *)malloc(12000000 * sizeof(double));
    double *data2 = (double *)malloc(12000000 * sizeof(double));
    FILE *f, *f2;
    cuDoubleComplex *se, *se2;

    f = fopen("ref_PRI20.dat", "r");
    fread(data, sizeof(double), n, f);
    fclose(f);

    f2 = fopen("surv_PRI20.dat", "r");
    fread(data2, sizeof(double), n, f2);
    fclose(f2);


    for (int a = 0; a < n; a++)
    {
        printf("%f\n", data2[a]);
    }


    se = (cuDoubleComplex*)malloc(lse * sizeof(cuDoubleComplex));
    se2 = (cuDoubleComplex*)malloc(lse * sizeof(cuDoubleComplex));
    for (int a = 0; a<n / 2; a++)
    {
        se[a].x = data[2 * a];
        se[a].y = data[2 * a + 1];
        se2[a].x = data2[2 * a];
        se2[a].y = data2[2 * a + 1];
    }  
free(data);
free(data2);

}

I have added the printf lines and bucle just to check and all I get is "0,0000" as a value. Although when I continue with the programm the se and se2 arrays seems to get random values. I know the size of the arrays is huge but I need to work with that amount of data.

I also have tried to work in matlab and I had no mistakes in there. This is the code that I used in matlab and everything was fine so I guess there is no problem with the .dat files but only with my code.

f = fopen ("ref_PRI20.dat", 'r');

Data = fread (f, 12e6, 'double');
fclose (f);

dat=(Data(1:2:end)+1i*Data(2:2:end)).';

Here's a scan of the input data so you can see the format. I hope it will help.

enter image description here

Any help will be appreciated.

Upvotes: 0

Views: 979

Answers (2)

xing
xing

Reputation: 2446

No error checking on the original code for malloc or fopen.
Since a comment said the file was opened in a text reader and had commas between values, fscanf should be used to input the values instead of fread.
Since the values must be scanned one at a time there isn't a need for the data or data2 pointers.
Could not compile this as I don't have cuComplex.h

#include "cuComplex.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

int main(void)
{
    int n = 12000000; //12.000.000
    int lse = n / 2;
    FILE *f, *f2;
    cuDoubleComplex *se, *se2;

    f = fopen("ref_PRI20.dat", "r");

    f2 = fopen("surv_PRI20.dat", "r");

    se = malloc(lse * sizeof(cuDoubleComplex));
    se2 = malloc(lse * sizeof(cuDoubleComplex));
    for (int a = 0; a < lse; a++)
    {
        if ( 1 != fscanf ( f, "%lf ,", &se[a * 2].x])) {
            fprintf ( stderr, "could not scan double\n");
            break;
        }
        if ( 1 != fscanf ( f, "%lf ,", &se[a * 2 + 1].y)) {
            fprintf ( stderr, "could not scan double\n");
            break;
        }
        if ( 1 != fscanf ( f2, "%lf ,", &se2[a * 2].x)) {
            fprintf ( stderr, "could not scan double\n");
            break;
        }
        if ( 1 != fscanf ( f2, "%lf ,", &se2[a * 2 + 1].y)) {
            fprintf ( stderr, "could not scan double\n");
            break;
        }
    }  
    fclose(f);
    fclose(f2);
    free ( se);
    free ( se2);
    return 0;
}

Upvotes: 1

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. cleanly compiles
  2. properly checks for and handles errors
  3. reads the data directly into the struct.
  4. Did not use the cuComplex.h file as that was not available.
  5. avoided the use of 'magic' numbers
  6. although the 'b' is not necessary in linux/unix, properly set the open mode to BINARY READ
  7. documented why each header file is included.
  8. eliminated all unnecessary variables and unnecessary calls to malloc()
  9. eliminated all unnecessary data copying.
  10. It may be desirable to read the data in a loop, using a 'moving window' until a 12000000 doubles are read. I'll let you add that feature, if necessary.

And now the proposed code:

#include <stdio.h>   // fopen(), fread(), printf(), fprintf(), perror()
#include <stdlib.h>  // exit(), EXIT_FAILURE, malloc(), free()


#define N 12000000

struct cuDoubleComplex
{
    double x;
    double y;
};

int main(void)
{
    struct cuDoubleComplex *data = malloc( (N>>1) * sizeof(double));
    if( !data )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }


    struct cuDoubleComplex *data2 = malloc( (N>>1) * sizeof(double));
    if( !data2 )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    FILE *f = fopen("ref_PRI20.dat", "rb");
    if( !f )
    {
        perror( "fopen failed" );
        free( data );
        free( data2 );
        exit( EXIT_FAILURE );
    }

    size_t nmemb = fread(data, sizeof(double), N, f);
    if( nmemb != N )
    {
        fprintf( stderr, "read of first file only read %lu doubles\n", nmemb );
        free( data );
        free( data2 );
        fclose( f );
        exit( EXIT_FAILURE );
    }

    fclose(f);

    FILE *f2 = fopen("surv_PRI20.dat", "rb");
    if( !f2 )
    {
        perror( "fopen failed" );
        free( data );
        free( data2 );
        exit( EXIT_FAILURE );
    }

    size_t nmemb2 = fread(data2, sizeof(double), N, f2);
    if( nmemb2 != N )
    {
        fprintf( stderr, "read of second file only read %lu doubles\n", nmemb2 );
        free( data );
        free( data2 );
        fclose( f2 );
        exit( EXIT_FAILURE );
    }

    fclose(f2);

    for (int a = 0; a < N; a++)
    {
        printf("%f\n", data2[a].y);
    }


    free(data);
    free(data2);
} // end function: main

Upvotes: 0

Related Questions