c - 在 C 中创建自定义 .txt 文件名时出现问题

标签 c

我在使用C创建自定义文件名时遇到问题。

我的目标是使用自定义文件名,以便为单独的实体打印数据。

我当前打印到文件的函数是:

void output(int t, double rx[], double ry[], double rz[], double vx[], double vy[], double vz[], double fx[], double fy[], double fz[])
{
    for(int i = 0; i < Npart; i++)
    {
        char name[20];
        sprintf(name, "Part_%d.txt", i);
        fptr = fopen(name, "a");
        fprintf(fptr, "%4d, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e\n", t, rx[i], ry[i], rz[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i]);   
    }
}

fptr 已使用 *FILE 进行初始化。 在此代码中,Npart 目前只有 2 个实体(通过 #define 设置为 2),在少量文件上休息该函数后,此数字将会增加,遗憾的是,在运行此代码时,它似乎适用于少量输出,直到准确地说每个文件达到464

之后我收到以下错误消息:

timestep made, time is 463 Segmentation fault (core dumped)

删除输出功能并在没有输出功能的情况下运行代码时,不会出现问题。我在这段代码中犯了任何明显的错误吗?

最佳答案

有一些明显的问题。

假设您希望为每个 Npart 创建一个文件,您的代码应类似于:

void output(int t, double rx[], double ry[], double rz[], double vx[], double vy[], double vz[], double fx[], double fy[], double fz[])
{
  char name[20];
  for(int i = 0; i < Npart; i++)
  {
    sprintf(name, "Part_%d.txt", i);
    fptr = fopen(name, "a");
    if(fptr)
    {
      fprintf(fptr, "%4d, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e\n", t, rx[i], ry[i], rz[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i]);
      fclose(fptr);
    }
    else
    {
      // Manage the error
      printf("Could not open %s for appending : %s\n", name, strerror(errno));
    }
  }
}

我在您的代码中看到了一些有问题的事情:

  • 为什么 fptr 在该函数之外声明?
  • 为什么Npart不是该函数的参数?如果能够向其传递任意数量的参数,将会更加灵活。
<小时/>

澄清后更新。

在尽可能小的范围内声明变量,并将所有内容放在一个结构中。

typedef struct sWhatever
{
  unsigned int Npart;
  int t;
  double* rx;
  double* ry;
  double* rz;
  double* vx;
  double* vy;
  double* vz;
  double* fx;
  double* fy;
  double* fz;
}
WHATEVER;

void output(WHATEVER * whatever)
{
  FILE* fptr;
  char name[20];
  for(int i = 0; i < whatever->Npart; i++)
  {
    sprintf(name, "Part_%d.txt", i);
    fptr = fopen(name, "a");
    if(fptr)
    {
      fprintf(fptr, "%4d, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e, %10.2e\n", whatever->t, whatever->rx[i], whatever->ry[i], whatever->rz[i], whatever->vx[i], whatever->vy[i], whatever->vz[i], whatever->fx[i], whatever->fy[i], whatever->fz[i]);
      fclose(fptr);
    }
    else
    {
      // Manage the error
      printf("Could not open %s for appending : %s\n", name, strerror(errno));
    }
  }
}

#define Npart (2)
int main(void)
{
  double rx[Npart];
  double ry[Npart];
  double rz[Npart];
  double vx[Npart];
  double vy[Npart];
  double vz[Npart];
  double fx[Npart];
  double fy[Npart];
  double fz[Npart];

  WHATEVER outputStruct;

  outputStruct.Npart = Npart;
  outputStruct.t = 42; // why not?
  outputStruct.rx = rx;
  outputStruct.ry = ry;
  outputStruct.rz = rz;
  outputStruct.vx = vx;
  outputStruct.vy = vy;
  outputStruct.vz = vz;
  outputStruct.fx = fx;
  outputStruct.fy = fy;
  outputStruct.fz = fz;

  output(&outputStruct);
}

这样,WHATEVER 的内容就可以更改,并且您只需对代码进行最小程度的更改。您还可以传递 WHATEVER 类型的变量的多个副本,这最终会发生。您可以拥有多个具有不同 Npart 值的 WHATEVER 变量,而无需声明 ouput() 的多个副本。最后,奖励点是,您的函数变得可重入,并且不会对全局变量产生副作用。

(免责声明:我还没有编译该代码,但它让您很好地了解该怎么做。)

关于c - 在 C 中创建自定义 .txt 文件名时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57910231/

相关文章:

c - 添加转换后对象呈现奇怪

java - 是否可以使用 SWIG 生成的 JNI 从 C 代码调用 java 方法?

c - 从mmaped NULL指针读取数据

c - 前向声明错误我无法理解

c - 如何在 C 编译时打印 sizeof() 的结果?

C 字符串追加

c - 生成位掩码的算法

c - 为什么 C 没有无符号 float ?

C - 在多个函数中使用结构

c - 如何获取当前事件的 Windows 资源管理器窗口的 HWND?