我正在尝试使用fwrite将数组写入二进制文件,因为我正在编写一个x-points流,后跟一个y-points流,顺序很重要。我希望写入输出,以便我的文件包含一对数组:
[ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]
[ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
如果我使用fprintf
写出文本文件并循环遍历数组索引,我会得到预期的输出顺序,但是当我使用下面的fwrite代码时,数据是按顺序写的。由于我使用的是一个简单的数组,因此我希望fwrite调用可以简单地按顺序写出整个数组。是不是这种情况,我误解或是我的错误在其他地方?
#include<stdlib.h>
#include<stdio.h>
#include<omp.h>
#define cache_align 0x40
#define xmin -2
#define ymin -2
#define xrange 4
#define yrange 4
#define xres 5
#define yres 5
#define num_particles (xres*yres)
int main(){
unsigned int stepnum = 0;
double* cx = aligned_alloc(cache_align, sizeof(double)*num_particles);
double* cy = aligned_alloc(cache_align, sizeof(double)*num_particles);
for(int ii=0; ii<xres; ii++){
for(int kk=0; kk<yres; kk++){
cx[ii*yres + kk] = ii;
cy[ii*yres + kk] = kk;
}
}
FILE* outfile;
char fname[100];
sprintf(fname, "out.bin");
outfile = fopen(fname,"wb");
if(!outfile){
printf("Unable to open output file!");
} else {
size_t written;
written = fwrite(cx,sizeof(double),num_particles,outfile);
written = fwrite(cy,sizeof(double),num_particles,outfile);
fclose(outfile);
}
return 0;
}
编辑:我应该添加我正在使用python检查数据输出:
import numpy as np
data = np.fromfile('out.bin','double',-1)
答案 0 :(得分:0)
目前还不清楚您是否为了简洁而省略了所有验证和错误检查,或者这只是您忽略的内容。您的索引问题由另一个答案正确解决。如果您有意省略了验证和错误检查,那么您可以在很大程度上忽略以下内容,如果没有,则考虑您负责验证代码中的每个步骤,这是后续操作所依赖的。 / p>
至少,这意味着验证所有内存分配,文件打开和文件关闭(用于写入)和号码在写入时写入的对象到数据文件。验证只是简单的检查,以确保您有一个有效的内存块,一个有效的文件流,您要写入的对象的数量实际写入,并且写入后文件上没有流错误。它们可以像文件流打开一样简单:
FILE *fp = argc > 1 ? fopen (fname, "wb") : stdout;
if (!fp) { /* validate file is open for writing */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
对于内存分配:
/* validate all memory allocation */
if (!(cx = aligned_alloc (cache_align, sizeof *cx * NPART))) {
fprintf (stderr, "error: virtual memory exhausted - cx.\n");
return 1;
}
验证写入文件的对象数量(written
为nobj
而num_particles
为NPART
- 我讨厌打字):
/* validate the number of objects written to file */
if ((nobj = fwrite (cx, sizeof *cx, NPART, fp)) != NPART)
fprintf (stderr, "warning: fwrite failure - cx.\n");
if ((nobj = fwrite (cy, sizeof *cy, NPART, fp)) != NPART)
fprintf (stderr, "warning: fwrite failure - cy.\n");
写入文件后关闭蒸汽:
if (fclose (fp)) /* validate the stream closure for writes */
fprintf (stderr, "error: fclose failed, data is suspect.\n");
最后,不要忘记释放你分配的内存。养成跟踪分配和释放每个分配的习惯,而不是依赖exit
为您的分配。在以后开始在各种功能中进一步分配时,这将是常规的。还可以通过内存错误检查程序运行代码,例如Linux上的valgrind
,以确保正确使用。
虽然您可以自由地检查您喜欢的数据,但只需编写验证功能就可以消除过程中的不确定性。例如,您可以简单地将现有数组传递给验证函数,并使该函数读取您编写的数据并提供每个值的比较。它只需要指出是否发生了错误。如果没有,那你就没事了。例如,一个简单的检查函数(为简单起见使用静态数组)可以是:
int chkdatafile (char *fn, double *a, double *b)
{
int err = 0;
size_t nobj = 0;
double cx[NPART] = {0.0}, cy[NPART] = {0.0};
FILE *fp = fopen (fn, "rb");
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: fopen failed '%s'.\n", fn);
return 1;
}
/* validate NPART object read into each array */
if ((nobj = fread (cx, sizeof *cx, NPART, fp)) != NPART) {
fprintf (stderr, "error: fread failure - cx.\n");
return 1;
}
if ((nobj = fread (cy, sizeof *cx, NPART, fp)) != NPART) {
fprintf (stderr, "error: fread failure - cy.\n");
return 1;
}
fclose (fp);
for (int i = 0; i < NPART; i++) /* validate cx read from file */
if (cx[i] != a[i]) {
fprintf (stderr, "error: cx[%2d] : (read) %02.0lf != %02.0lf\n",
i, cx[i], a[i]);
err = 1;
}
for (int i = 0; i < NPART; i++) /* validate cy read from file */
if (cy[i] != b[i]) {
fprintf (stderr, "error: cx[%2d] : (read) %02.0lf != %02.0lf\n",
i, cy[i], b[i]);
err = 1;
}
return err;
}
您可以通过以下类似的程序从您的程序中调用它:
if (chkdatafile (fname, cx, cy))
fprintf (stderr, "error: data in '%s' is invalid.\n", fname);
就像我说的那样,如果你故意省略了支票,那么我不会告诉你任何你不知道的事情,如果不是,那么请尽早养成习惯,以便随时验证以后所依赖的任何事情。在你的代码中。从长远来看,它将为您节省大量的调试时间等。
将所有部分放在一起,将输出文件名作为程序的第一个参数(如果没有给出输出文件名,只需将值写入stdout
),您可以提供如下最小化检查:
#include <stdlib.h>
#include <stdio.h>
#define cache_align 0x40
#define XRES 5
#define YRES 5
#define NPART (XRES*YRES)
int chkdatafile (char *fn, double *a, double *b);
int main (int argc, char **argv) {
size_t nobj;
double *cx, *cy;
char *fname = argc > 1 ? argv[1] : "stdout";
FILE *fp = argc > 1 ? fopen (fname, "wb") : stdout;
if (!fp) { /* validate file is open for writing */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* validate all memory allocation */
if (!(cx = aligned_alloc (cache_align, sizeof *cx * NPART))) {
fprintf (stderr, "error: virtual memory exhausted - cx.\n");
return 1;
}
if (!(cy = aligned_alloc (cache_align, sizeof *cy * NPART))) {
fprintf (stderr, "error: virtual memory exhausted - cx.\n");
return 1;
}
for (int i = 0; i < XRES; i++)
for (int k = 0; k < YRES; k++) {
cx[k * YRES + i] = i;
cy[k * YRES + i] = k;
}
if (argc > 1) { /* validate the number of objects written */
if ((nobj = fwrite (cx, sizeof *cx, NPART, fp)) != NPART)
fprintf (stderr, "warning: fwrite failure - cx.\n");
if ((nobj = fwrite (cy, sizeof *cy, NPART, fp)) != NPART)
fprintf (stderr, "warning: fwrite failure - cy.\n");
}
else {
for (int i = 0; i < NPART; i++)
printf (" %02.0lf", cx[i]);
putchar ('\n');
for (int i = 0; i < NPART; i++)
printf (" %02.0lf", cy[i]);
putchar ('\n');
}
if (fp != stdout) {
if (fclose (fp)) /* validate the stream closure for writes */
fprintf (stderr, "error: fclose failed, data is suspect.\n");
if (chkdatafile (fname, cx, cy))
fprintf (stderr, "error: data in '%s' is invalid.\n", fname);
}
free (cx); /* free all allocated memory */
free (cy);
return 0;
}
int chkdatafile (char *fn, double *a, double *b)
{
int err = 0;
size_t nobj = 0;
double cx[NPART] = {0.0}, cy[NPART] = {0.0};
FILE *fp = fopen (fn, "rb");
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: fopen failed '%s'.\n", fn);
return 1;
}
/* validate NPART object read into each array */
if ((nobj = fread (cx, sizeof *cx, NPART, fp)) != NPART) {
fprintf (stderr, "error: fread failure - cx.\n");
return 1;
}
if ((nobj = fread (cy, sizeof *cx, NPART, fp)) != NPART) {
fprintf (stderr, "error: fread failure - cy.\n");
return 1;
}
fclose (fp);
for (int i = 0; i < NPART; i++) /* validate cx read from file */
if (cx[i] != a[i]) {
fprintf (stderr, "error: cx[%2d] : (read) %02.0lf != %02.0lf\n",
i, cx[i], a[i]);
err = 1;
}
for (int i = 0; i < NPART; i++) /* validate cy read from file */
if (cy[i] != b[i]) {
fprintf (stderr, "error: cx[%2d] : (read) %02.0lf != %02.0lf\n",
i, cy[i], b[i]);
err = 1;
}
return err;
}
如果您提供输出文件名并且没有收到任何错误,则所有内容都按预期进行。仔细看看,如果您有任何问题,请告诉我。