如何从多个.dat文件输入?

时间:2013-11-04 12:26:10

标签: c++ input multiple-columns

我有一组.dat格式的101个文件(全部包含在同一目录中),带有递归名称: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

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

2 个答案:

答案 0 :(得分:0)

第一个问题是make_output_filename的展示位置。这个很容易,因为编译器指出了它。您可以在main之前移动它。

然而,我发现另一个问题几乎肯定会上升:

size_t i = n * 0.02;

我不确定如何验证文件名,并且显然无法编译代码。但我99%肯定会导致问题。 size_t是一个整数类型,因此乘以类似0.02的东西总是很危险的。它将向下舍入到0,因此至少大约前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 ;
   }
}

答案 1 :(得分: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中的值)。 是否有一些更聪明(即计算更快)的方法呢? 谢谢