1

したがって、基本的に次のようなファイル 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

そして、最初の 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ループから外すと、最後のデータ行のみが出力されます

4

2 に答える 2

2

問題の 1 つは、コメントを受け取っても、常に数値を出力することです。また、ピークと無視のものは必要ありません。数値が正常に読み取られたかどうかを確認するには、次の例のように、読み取り後にストリームをブール値として評価するだけです。

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

この例では、ファイルの代わりに標準入出力を使用しています。これらが「標準」と呼ばれる理由は次のとおりです。これらは非常に柔軟で、ファイルや他のプロセスとの間で非常に簡単にリダイレクトできます。しかし、プログラムはファイルと非常によく似ています。

于 2012-10-30T19:36:59.527 に答える
1

入力が成功したことを常に確認する必要があります。また、奇妙な文字ベースの読み取りテクニックに頼る必要はほとんどありません。たとえば、先頭の空白をスキップするマニピュレータがあります: std::ws. 以下は、値の型についてあまり仮定しないバージョンです。行の最初の値が整数でなければならない場合は、int代わりに使用std::stringでき、コメント行のチェックをスキップすることもできます! 3 つの値の読み取りが成功したことを確認するだけです。

#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';
        }
    }
}
于 2012-10-30T19:49:35.480 に答える