C 使用fwrite时的置乱数组顺序

C 使用fwrite时的置乱数组顺序,c,io,C,Io,我试图使用fwrite将数组写入一个二进制文件,当我在写一个x点流和一个y点流时,顺序很重要。我希望写入输出,以便我的文件由一对数组组成: [ 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将数组写入一个二进制文件,当我在写一个x点流和一个y点流时,顺序很重要。我希望写入输出,以便我的文件由一对数组组成:

[ 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;
}

不清楚您是否为了简洁而忽略了所有验证和错误检查,或者这只是您忽略的东西。另一个答案正确地解决了索引问题。如果您忽略了验证和错误检查是有意的,那么您可以在很大程度上忽略下面的内容,如果没有,那么就认为您有责任验证代码中的每一步,这取决于后续操作。 至少,这意味着验证所有内存分配、文件打开和文件关闭(用于写入)以及写入时写入数据文件的对象数。验证只是简单的检查,以确保您有一个有效的内存块、一个有效的文件流、您打算写入的对象的数量实际上已写入,并且在写入后关闭文件时没有流错误。对于文件流打开,它们可以如下所示:

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;
}
验证写入文件的对象数(您的
写入的
nobj
,您的
num\u粒子
NPART
——我讨厌键入):

对于写入文件后蒸汽关闭:

    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;
}
就像我说的,如果你故意省略了检查,那么我不会告诉你任何你还不知道的事情,如果他们不知道,那么就养成习惯,尽早验证代码中以后依赖的任何东西。从长远来看,它将为您节省大量调试等时间

将所有部分放在一起,将输出文件名作为程序的第一个参数(如果没有给出输出文件名,只需将值写入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;
}
#包括
#包括
#定义缓存\u对齐0x40
#定义XRES 5
#定义YRES 5
#定义NPART(XRES*YRES)
int chkdatafile(char*fn,double*a,double*b);
int main(int argc,字符**argv){
大小(nobj);;
双*cx,*cy;
char*fname=argc>1?argv[1]:“stdout”;
文件*fp=argc>1?fopen(fname,“wb”):标准输出;
如果(!fp){/*验证文件已打开以进行写入*/
fprintf(stderr,“错误:文件打开失败“%s”。\n”,argv[1]);
返回1;
}
/*验证所有内存分配*/
如果(!(cx=aligned\u alloc(cache\u align,sizeof*cx*NPART))){
fprintf(stderr,“错误:虚拟内存耗尽-cx.\n”);
返回1;
}
如果(!(cy=aligned\u alloc(cache\u align,sizeof*cy*NPART))){
fprintf(stderr,“错误:虚拟内存耗尽-cx.\n”);
返回1;
}
对于(int i=0;i1){/*验证写入的对象数*/
if((nobj=fwrite(cx,sizeof*cx,NPART,fp))!=NPART)
fprintf(标准,“警告:写入失败-cx.\n”);
如果((nobj=fwrite(cy,sizeof*cy,NPART,fp))!=NPART)
fprintf(标准,“警告:写入失败-cy.\n”);
}
否则{
对于(int i=0;iint 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);
#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;
}