C ++:如何将数据输出到多个.dat文件?

时间:2012-11-16 17:03:40

标签: c++ c gnuplot string-building

我正在研究一个研究项目。我是C ++和一般编程的初学者。我已经制作了一个程序,可以生成相互作用的粒子,随着时间的推移在连续的空间上移动。我的程序输出的唯一内容是每个时间步中每个粒子的XY坐标。

我想想象我的发现,知道我的粒子是否正在移动。我的教授说我必须使用gnuplot。由于我找不到在一个文件中输出数据的方法,以便gnuplot能够识别它,我想到了以下策略:

a)对于每个时间步,生成一个XY坐标格式为“output_#.dat”的文件。

b)在.png中为每个人生成gnuplot个文件。

c)制作包含所有.png个文件的移动粒子的电影。

我稍后会担心b和c,但到目前为止,我可以使用以下代码将所有数据输出到一个文件中:

    void main()
{
    int i = 0;
    int t = 0; // time
    int j = 0; 
    int ctr = 0;
    double sumX = 0;
    double sumY = 0;
    srand(time(NULL)); // give system time as seed to random generator


    Cell* particles[maxSize]; // create array of pointers of type Cell.

    for(i=0; i<maxSize; i++) 
    {
        particles[i] = new Cell(); // initialize in memory
        particles[i]->InitPos(); // give initial positions
    }

    FILE *newFile = fopen("output_00.dat","w"); // print initial positions
    for(i=0; i<maxSize; i++)
    {
        fprintf(newFile, "%f %3 ", particles[i]->getCurrX());
        fprintf(newFile, "%f %3 \n", particles[i]->getCurrY());
    }
    fclose(newFile);

    FILE *output = fopen("output_01.dat","w");
    for(t = 0; t < tMax; t++)
    {
        fprintf(output, "%d ", t);
        for(i=0; i<maxSize; i++) // for every cell
        {
            sumX = 0;
            sumY = 0;
            for(j=0; j<maxSize; j++) // for all surrounding cells
            {
                sumX += particles[i]->ForceX(particles[i], particles[j]);
                sumY += particles[i]->ForceY(particles[i], particles[j]);
            }
            particles[i]->setVelX(particles[i]->getPrevVelX() + (sumX)*dt); // update speed
            particles[i]->setVelY(particles[i]->getPrevVelY() + (sumY)*dt);
            particles[i]->setCurrX(particles[i]->getPrevX() + (particles[i]->getVelX())*dt); // update position
            particles[i]->setCurrY(particles[i]->getPrevY() + (particles[i]->getVelY())*dt);

            fprintf(output, " ");
            fprintf(output, "%f %3 ", particles[i]->getCurrX());
            fprintf(output, "%f %3 \n", particles[i]->getCurrY());
        }
    }
    fclose(output);
}

这确实会生成2个文件output_00.datoutput01.dat,第一个包含初始随机生成的位置,第二个包含我的所有结果。

我可以感觉到,在嵌套for循环中,我正在更新XY坐标的速度和位置,我可以有FILE*来存储每个时间步的坐标和然后关闭它,然后再增加时间。这样,我不需要多个指针同时打开。至少这是我的直觉。

我不知道如何生成递增的文件名。我偶然发现了ofstream,但我不明白它是如何运作的......

我认为我希望我的程序在这一点上做的是:

1)使用基本名称和当前循环计数器值生成新文件名。

2)打开该文件。

3)写下该时间步的坐标。

4)关闭文件。

5)重复。

任何帮助将不胜感激。谢谢你的时间!

1 个答案:

答案 0 :(得分:2)

使用ofstream而不是fopen可以更好地使用C ++标准库,而现在你正在使用C标准库调用,但是现在没有任何错误的与你现在正在做的事情

看起来您真正的核心问题是如何从整数生成文件名,以便您可以在循环中使用它:

这是一种方式:

// Include these somewhere
#include <string>
#include <sstream>

// Define this function
std::string make_output_filename(size_t index) {
   std::ostringstream ss;
   ss << "output_" << index << ".dat";
   return ss.str();
}

// Use that function with fopen in this way:
for (size_t output_file_number=0; /* rest of your for loop stuff */)  {
  FILE *file = fopen(make_output_filename(output_file_number).c_str(), "w");
  /* use the file */
  fclose(file);
}

这使用了std :: ostringstream&#34;使用流操作构建文件名,并返回构建的std :: string。当你把它传递给fopen时,你必须给它一个const char *而不是std :: string,所以我们使用.c_str()成员,它只是为了这个目的而存在。