0

我有一组 101 个.dat格式的文件(全部包含在同一目录中),具有递归名称:smth_0.00.dat, smth_0.02.dat, smth_0.04.dat等。它们由两组数据组成:两列浮点数。我需要从每个文件中提取第 n 行数据并对其进行处理并对所有 n 行重复此操作,以获得 n 个不同的值。

我的问题是:

  • 创建/使用正确的字符串流递归地创建正确的 100 个文件名
  • 打开它
  • 找到一种聪明的方法来选择(在每个文件中)第 n 行,而不必进行 for 循环来读取整个列

我试图在stackoverflow上结合其他问题的信息,这就是我想出的:

using namespace std;

int main ()
{
        const int tot = 101 ; 

        std::string make_output_filename(size_t index) {
                std::istringstream ss;
                ss << "/filename_" << index << ".dat";
                return ss.str();
        }


        for (size_t n=0; n < tot; n++ )  {
                size_t i = n * 0.02 ;
                FILE *file = fopen(make_output_filename(i).c_str(), "r");
                cout << file << endl ;
                fclose(file);
        }
}

如您所见,目前我只是通过在屏幕上打印代码来验证代码是否创建了正确的文件名。然后打开只是使用的问题

ifstream in; 
in.open("filename_0.00.dat");

但是,如果我尝试编译它,我会收到两条错误消息:

get_from_file4.cpp: In function ‘int main()’:
get_from_file4.cpp:12: error: a function-definition is not allowed here before ‘{’ token
get_from_file4.cpp:21: error: ‘make_output_filename’ was not declared in this scope

有人可以帮我摆脱这个问题吗?

4

2 回答 2

0

我设法取得了很多成就。我当前的(工作)代码是:

    string make_output_filename(float number) {
    stringstream ss;
    ss.setf(ios_base::fixed);
    ss.precision(2);
    ss << "/powerspectrum/cdm_matterpower_" << number << ".dat";
    return ss.str();
}

int main ()
{
    const int Nfile = 101 ;
    const int Nvalues = 926 ;
    double x[Nvalues], y[Nvalues], PowerL[Nvalues][Nfile] ;

    for (int l=0; l<Nvalues; l++) {
        for (int z=0; z < Nfile; z++ )  {
            float number = z * 0.02 ;
            cout << make_output_filename(number) << endl ;
            ifstream redout ;
            redout.open(make_output_filename(number).c_str());

            int nlines = 0 ;
            while (nlines < Nvalues) {
                redout >> x[Nvalues] >> y[Nvalues] ;
                if (nlines == l) {
                    PowerL[l][z] = y[Nvalues] ;
                    cout << "l = " << l << " , K = " << x[Nvalues] << " , P(k) = " << PowerL[l][z] << endl ;
                }
                if (!redout.good()) {
                    break;
                }
                nlines++;
            }
            redout.close() ;
        }
    }
}

但是,正如您所看到的,它在每个 z for 循环中读取整个文件(以便提取然后存储在 PowerL 中的值)。有没有更聪明(即计算速度更快)的方法呢?谢谢你

于 2013-11-05T14:13:09.653 回答
0

第一个问题是make_output_filename. 正如编译器指出的那样,这很容易。你可以先移动它main

但是,我看到另一个几乎肯定会出现的问题:

size_t i = n * 0.02;

我不确定您如何验证文件名,因为代码显然无法编译。但我有 99% 的把握这会导致问题。size_t是一个整数类型,所以将它乘以类似的东西0.02总是很危险的。0对于我希望看到的至少大约 1st 50 次迭代,它将被四舍五入filename_0

在你的情况下,我会做i一个浮点数并在ss里面设置适当的流标志make_output_filename

如果我把一切都做对了,决赛看起来会像这样。

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

string make_output_filename(float number) {
  stringstream ss;
  ss.setf(ios_base::fixed);
  ss.precision(2);
  ss << "/filename_" << number << ".dat";
  return ss.str();
}

int main ()
{
   const int tot = 101 ; 
   for (size_t n=0; n < tot; n++ )  {
     float number = n * 0.02 ;
     cout << make_output_filename(number) << endl ;
   }
}
于 2013-11-04T12:47:25.457 回答