我想读取一个 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
x
和 v
重新赋给指向数组,在下面的 for
中有问题,调用 free
将尝试 free
数组而不是原来的 malloc
ed 指针。
如果你不需要以人类可读的格式存储数据,那么你可以使用这个
#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/