我在使用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/