istringstream不在变量中存储任何内容

时间:2013-12-12 19:55:58

标签: c++ file variables

我遇到istringstream没有存储它读取的值的问题。这就是我所拥有的:

      if(inputFile.good()){                                         //Make sure file is open before trying to work with it
                                                                    //Begin Working with information
        cout << "\tIn File:  " << input << endl;
        cout << "------------------------------------" << endl;
        int number_of_lines = 0;
        std::string line;
        while (std::getline(inputFile, line)){
            ++number_of_lines;
        }
        Time times[number_of_lines];
        double math[number_of_lines];
        std::string input;
        int hh, mm;
        for(int loop=0;loop<number_of_lines;loop++){
            std::getline(inputFile, input);
            std::istringstream(input) >> mm >> hh >> math[loop];
            cout << "hours = " << hh << endl;
            times[loop].setTimeHours(hh);
            times[loop].setTimeMinutes(mm);
            times[loop].show();
            cout << "*" << math[loop] << endl;
        }
        std::cout << "Number of lines in text file: " << number_of_lines << "\n" << endl;
    }else{
        cout << "Could not open file!!!" << endl;
    }

我正在阅读的文件如下:

90 1 3.0
1 1 100.0
2 34 5.1

我跑的输出:

  In File:  data04.txt
 ------------------------------------
 hours = 0
 Operation To Be Done = 0:2336552*1.15384e-317
 hours = 0
 Operation To Be Done = 0:2336552*1.58101e-322
 hours = 0
 Operation To Be Done = 0:2336552*1.15397e-317
 Number of lines in text file: 3

任何人都知道为什么它不存储值?

2 个答案:

答案 0 :(得分:2)

此代码中存在几个关键问题

  1. 不检查输入是否成功。您始终需要确保在处理您阅读的数据之前验证输入操作是否有效。如果失败将导致处理随机数据。
  2. 您首先阅读流的末尾,然后希望流神奇地重新启动。那不行。只读一次流并继续追加到std::vector<Time>(或类似的容器)。除了遍历文件一次之外,在UNIX上,文件大小可以在读取时改变。
  3. C ++没有可变大小的数组,尽管某些编译器可能提供类似于C的可变大小数组的扩展。在C ++中,您使用的是std::vector<Time>

答案 1 :(得分:0)

首先,你的程序是错误的。 while循环结束后,文件中无需读取任何内容(除非您seekg()回到开头),因此std::getline()循环体中的for调用基本上什么也没做。

第二个问题是关注点没有恰当地分开。

以下是我将如何实施此计划:

struct line_data
{
  Time   t;
  double x;
};

// This handles reading a single Time value.
std::istream & operator >> (std::istream & is, Time & t)
{
  int hh, mm;
  if (is >> hh >> mm)
  {
    // Not happy with the following two lines, too Java-like. :-(
    t.setTimeHours(hh);
    t.setTimeMinutes(mm);
  }
  return is;
}

// This handles reading a single line of data.
std::istream & operator >> (std::istream & is, line_data & ld)
{
  std::string s;
  if (std::getline(is, s))
  {
    std::istringstream iss(s);
    // Ensure errors are propagated from iss to is.
    if (!(iss >> ld.t >> ld.x))
      is.setstate(std::ios::failbit);
  }
  return is;
};

// This handles processing a single line of data.
struct line_manip // satisfies concept OutputIterator<line_data>
{
  std::back_insert_iterator<std::vector<Time>>   ti;
  std::back_insert_iterator<std::vector<double>> xi;

  line_manip(std::vector<Time> & ts, std::vector<double> & xs)
    : ti(std::back_inserter(ts))
    , xi(std::back_inserter(xs))
  {
  }

  line_manip & operator = (const line_data & ld)
  {
    ti = ld.t;
    xi = ld.x;
    return *this;
  }

  line_manip & operator *  ()    { return *this; }
  line_manip & operator ++ ()    { return *this; }
  line_manip & operator ++ (int) { return *this; }
};

int main()
{
  std::ifstream ifs("input.txt");
  std::vector<Time>   ts;
  std::vector<double> xs;
  std::copy(std::istream_iterator<line_data>(ifs),
            std::istream_iterator<line_data>(),
            line_manip(ts, xs));
  // ...
}