2012-05-09 54 views
1

我拼命试图通过使用fstream:列产生格式化输出。格式化输出:列

有两个函数(无论函数func1的,FUNC2),其产生输出(写入到相同的文件, “example.dat”):

#include <fstream> 

int main() 
{ 
    std::ofstream fout;  
    fout.open("example.dat"); 

    for (int i=0; i<10; i++) 
    { 
     fout << Func1(i) << std::endl; 
    }; 

    // Func2 depends on Func1, thus them **cannot** be written at the same time: 
    // fout << Func1() << " " << Func2() << std::endl; 

    for (int i=0; i<10; i++) 
    { 
     fout << Func2(i) << std::endl; 
    }; 

    return 0; 
} 

输出将类似于:

FUNC1 (0)

Func1(1)

。 。

FUNC1(9)

FUNC2(0)

FUNC2(1)

FUNC2(9)

我的问题是:如何产生这种输出作为两列:

FUNC1(0)FUNC2(0)

FUNC1(1)FUNC2(1)

虽然它们不是同时写入。

我怀疑我需要使用seekp(),tellp(),但不幸的是我不是这方面的大专家。

请帮忙!

预先感谢您。

+0

你就不能缓冲FUNC1和FUNC2的输出分为2'载体'这样就可以输出结果在一个循环columnated? – Benj

+0

谢谢BENJ, – Pomeron

+1

您应该编辑您的问题,从标题中删除(C++)。如果您拥有C++标记,则不需要将其放入。 – tinman

回答

0

为什么你需要seekp和tellp(和写入文件的中间是充满陷阱粗心的在任何情况下)

使用一个std ::向量(语法可能是错误的),这样的:

std::vector<std::string> res1; 
std::vector<std::string> res2; 
res1.reserve(10); 
res2.reserve(10); 
for (std::size_t i = 0; i < 10; ++i) 
{ 
    std::stringstream s; 
    s << func1(i); 
    res1[i] = s.str(); 
} 
//same for res2, func2 
for (std::size_t i = 0; i < 10; ++i) 
{ 

    cout << res1[i] << " " << res2[i] << "\n"; 
} 

这可能是错误的格式和位需要调整。而std :: list可能会更好。

+0

谢谢Benj和Tom Tanner,代码abvoe只是我原始代码的原型。其实,我有大约100列,每个长度〜50^4。将它们全部保存在内存中可能会杀死它。因此,我有兴趣将它写入我的.dat文件,释放内存并再次运行(数据的下一部分)。 – Pomeron

0

假设你真的无法将它们保存在内存中,你可以写入两个文件,回溯到开始,逐行阅读并输出到最终文件以创建连接列。

像这样的东西可能工作(我没有测试过):

#include <fstream> 
#include <string> 
int main() 
{ 
    std::fstream fs_func1; 
    std::fstream fs_func2; 
    std::ofstream fout; 

    fs_func1.open("func1.dat") 
    for (int i=0;i<10;i++) 
    { 
     fs_func1 << Func1(i) << std::endl; 
    } 
    fs_func1.seekg(0); // Set get pointer to start of file 

    fs_func2.open("func2.dat"); 
    for (int i=0;i<10;i++) 
    { 
     fs_func2 << Func2(i) << std::endl; 
    }; 
    fs_func2.seekg(0); // Set get pointer to start of file 

    fout.open("example.dat"); 
    while (!fs_func1.eof() && !fs_func2.eof()) 
    { 
     std::string func1_line; 
     std::string func2_line; 

     std::getline(fs_func1, func1_line); 
     std::getline(fs_func2, func2_line); 

     fout << func1_line << " " << func2_line << std::endl; 
    } 

    return 0; 
} 

有可能是一个Unix命令行工具,它在一步为你做这个。

+0

谢谢锡曼!但在我的情况下,连接列应该增量显示。由于我处理大量数据文件,因此读取和写入操作将非常耗时。因此,我需要保持(打开?)主文件“example.dat”,并在每次运行后每次添加一个新列。你提供了一个非常好的解决方案,但是如何改变为增量型? – Pomeron

+0

@Pomeron:我认为您不能轻易将我的代码更改为增量代码,除非您可以将for循环拆分为更小的部分,例如调用Func1()为0 ... 9,然后Func2()为0 ... 9,然后Func1()为10 ... 19等。那么,你可以改变它,但它会是完全不同的东西。 – tinman

-1
for (int i=0;i<10;i++) 
{ 
    fout << Func1(i); 
}; 
fout<<endl; 

for (int i=0;i<10;i++) 
{ 
    fout << Func2(i); 
}; 
fout<<endl; 
+0

我不是downvoter,但会产生两行,不是两列的输出。如果您更改答案以显示如何将其转换为两列,那么这可能是一个很好的答案。 – tinman

0
vector<ostringstream> streams(10); 

for (int i=0; i < 10; ++i) 
{ 
    streams[i] << Func1(i); 
} 

for (int i=0; i < 10; ++i) 
{ 
    streams[i] << " " << Func2(i); 
} 

ofstream fout("example.dat"); 

for (int i=0; i < 10; ++i) 
{ 
    fout << streams[i].str() << endl; 
} 
+0

不错的解决方案!但是,它能够存储在大约600 MB的矢量中吗? – Pomeron

+0

我有100个“for”循环,每个循环产生〜6-7MB的.dat文件。所以,为了使用你的解决方案,我必须存储100X(6-7MB)的信息。它可能用于“矢量”吗? – Pomeron

+0

你的意思是你有100列?也许中间文件是要走的路。 –

0

未经检验的,但这个想法是把你的文件作为一个网格。

const int COLUMN_COUNT = 2; 
const int COLUMN_WIDTH = 8; 
const int ROW_WIDTH = COLUMN_COUNT * COLUMN_WIDTH + 1; // + 1 is for endl 

void write_cell(std::ostream& out, int row, int column, double value) { 

    // how many rows is there in the file ? 
    out.seekp(0, std::ios_base::end); 
    int row_count = out.tellp()/ROW_WIDTH; 

    // Do we need to create more rows ? 
    for(int i = row_count; i <= row; i++) { 
    out.seekp(ROW_WIDTH - 1, std::ios_base::cur); 
    out << endl; 
    } 

    // compute cell position 
    int pos = row * ROW_WIDTH + column * COLUMN_WIDTH; 

    // move to cell position 
    out.seekp(pos); 

    // write the cell content 
    out << std::setw(COLUMN_WIDTH) << value; 
} 

int main() 
{ 
    std::ofstream fout;  
    fout.open("example.dat"); 

    for (int i=0; i<10; i++) 
    { 
    write_cell(fout, i, 0, Func1(i)); 
    }; 

    for (int i=0; i<10; i++) 
    { 
    write_cell(fout, i, 1, Func2(i)); 
    }; 

    return 0; 
}