sstream使用输入和输出文件

时间:2012-10-30 19:26:37

标签: c++

所以我有一个文件data3.txt,它基本上是这样的:

#file:data.txt
#data inputs
1 1234 +0.2 23.89 6.21
2 132 -0.03 3.22 0.1
3    32 0.00 31.50   4.76

我想使用stringtreams

将前3列写入新文件
#include <cctype>
#include <sstream>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
int main(){
  string line;
  float curr_price, change;
  int stock_number;
  ifstream fin("data3.txt");
  istringstream iss;
  ostringstream oss;
  if(!fin){
    cerr<<"Can't open a file";
  }
  ofstream outfile("data2.txt");
  while (getline(fin,line)){
    iss.clear();
    iss.str(line);
    iss>>stock_number>>curr_price>>change;
    while(isspace(iss.peek()))
      iss.ignore();
    while(iss.str() == "#")
      iss.ignore();
    if( iss.str()==""){
      break;
    }
    oss<<stock_number<<"\t"<<curr_price<<"\t"<<change<<"\n";
    outfile<<oss.str();
  }
}

但是我的输出文件看起来很讨厌:

0   0   0
0   0   0
0   0   0
0   0   0
0   0   0
1   1234    0.2
0   0   0
0   0   0
1   1234    0.2
2   132 -0.03
0   0   0
0   0   0
1   1234    0.2
2   132 -0.03
3   32  0

我不知道零来自哪里,如果我将ofstream放入while循环,那么它只会打印最后一个数据行

2 个答案:

答案 0 :(得分:2)

一个问题是,即使您收到评论,也始终输出数字。此外,偷看和忽略的东西不应该是必要的。要检查数字是否已成功读取,只需在读取后将流评估为布尔值,就像我在此示例中所做的那样:

#include <fstream>
#include <sstream>
using namespace std;

int main(int argc, char ** argv)
{
    ifstream in(argv[1]);
    ofstream out(argv[2]);
    string line;
    while(getline(in,line))
    {
        if(line.empty() || line[0] == '#') continue;
        double number, price, change;
        stringstream ss(line);
        if(ss >> number >> price >> change)
            out << number << "\t" << price << "\t" << change << "\n";
    }
    return 0;
}

顺便说一下,这是一个使用某些C函数会使事情变得更简单和更漂亮的例子:

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;

int main(int argc, char ** argv)
{
    string line;
    int number;
    double price, change;
    while(getline(cin,line))
        if(sscanf(line.c_str(), "%d %lf %lf", &number, &price, &change)==3)
            printf("%3d %8.2f %8.2f\n", number, price, change);
    return 0;
}

此示例使用标准输入和输出而不是文件。这些被称为“标准”有一个原因:它们非常灵活,可以非常简单地重定向到文件和其他进程。但该程序与文件非常相似。

答案 1 :(得分:1)

您需要始终检查您的输入是否成功!此外,您很少需要采用基于奇怪角色的阅读技巧。例如,有一个操纵器可以跳过前导空格:std::ws。下面是一个版本,它没有对值的类型做出太多假设。如果一行中的第一个值必须是整数,则可以使用int而不是std::string,甚至可以跳过对注释行的检查!您只需检查读取三个值是否成功。

#include <sstream>
#include <fstream>
#include <string>

int main()
{
    std::ifstream      in("input.txt");
    std::ofstream      out("output.txt");
    std::istringstream lin;
    std::string        tmp0, tmp1, tmp2;
    for (std::string line; std::getline(in, line); ) {
        lin.clear();
        lin.str(line);
        if ((lin >> std::ws).peek() != '#'
            && lin >> tmp0 >> tmp1 >> tmp2) {
            out << tmp0 << '\t' << tmp1 << '\t' << tmp2 << '\n';
        }
    }
}