格式化输出:列

时间:2012-05-09 09:58:27

标签: c++ fstream formatted

我正在拼命尝试使用fstream:columns生成格式化输出。

有两个函数(无论函数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(),但遗憾的是我不是这方面的专家。

请帮忙!

提前谢谢。

5 个答案:

答案 0 :(得分:1)

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;
}

答案 1 :(得分:0)

为什么你需要seekp和tellp(在任何情况下,写入文件的中间都会给那些粗心的人带来陷阱)

使用std :: vector(语法可能不对),因此:

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可能会更好。

答案 2 :(得分: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命令行工具可以一步完成。

答案 3 :(得分: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;
}

答案 4 :(得分:-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;