2012-10-30 64 views
1

所以我有一个文件data3.txt基本上是这样的:sstream使用输入和输出文件

#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 

而且我要采取的第一个3列使用stringtreams

写入到一个新文件
#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循环,然后它只会显示最后数据行

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

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

+0

非常感谢,这是非常有益的 –

+0

我刚刚得到一个问题请问这个第一implemenetation使用ostringstream和istringstream? –

+0

它没有,所以如果这是关键的我想这是不是你所期待的。 ostringstream对于你正在做的事不是必需的,所以我没有使用它。由于其标记属性,istringstream很有用。我使用了一个普通的stringstream,但它可能已被替换为istringstream而没有任何更改。 – amaurea

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