如何用c ++中的文本文件填充数组

时间:2014-04-15 13:38:17

标签: c++ file class ifstream

您好我正在尝试填写我创建的类对象的数组。输入来自文本文件。文本文件包含字符串和数字。我得到了第一组信息,但文件的其余部分将无法读入,任何想法都将不胜感激!

    class mess
    {
        private: 
            string name;
            float age, weight, height;
        public: 
            void setname(string a) {name=a;}
            void setage(float b){age=b;}
            //etc.
            string getname(){return name;}
            float getage(){return age;}
            //etc.
    }

    ifstream input;
    input.open("test.txt");

    mess people[2]
    string str;
    float num;

    for(inti=0; i<2; i++)
    {
        getline(input,str,'\n');
        people[i].setname(str);

        input >> num;
        people[i].setage(num);

        input >> num;
        people[i].setweight(num);

        input >> num;
        people[i].setheight(num);
    }
    for(inti=0; i<2; i++)
    {
        cout << people[i].getname() << endl;
        cout << people[i].getage() << endl;
        cout << people[i].getweight() << endl;
        cout << people[i].getheight() << endl;
    }

的test.txt

jack
17    150.3    5.10
Amy
18    110.4    5.11

输出:

Jack
17
150.3
5.10
(blank)
0
0
0

3 个答案:

答案 0 :(得分:3)

这里的问题是当你使用输入操作符>>时,它将在第一个记录的最后一个数字之后留下换行符。这意味着下一个getline调用会将该换行读为空行,然后这些数字将无法读取。

有几种方法可以解决这个问题。第一种是在读取记录中的最后一个数字后丢弃输入中的所有文本,直到换行。为此,你可以这样做。

// All other input in loop

input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

了解ignore功能。

另一种方法是阅读第二行,完成并将其放入std::istringstream,然后从中读出数字:

// Reading the name...

std::string numbers;
std::getline(input, numbers);

std::istringstream istr(numbers);

istr >> num;
people[i].setage(num);

// ...

另请注意,std::getline的第三个参数已默认为换行符,因此如果您使用它来读取换行符,则无需提供换行符。

答案 1 :(得分:0)

我建议您在班级中重载运算符<<>>

class mess
{
    private: 
        string name;
        float age, weight, height;
    public: 
        void setname(string a) {name=a;}
        void setage(float b){age=b;}
        //etc.
        string getname(){return name;}
        float getage(){return age;}
        //etc.
        friend std::istream& operator>>(std::istream& inp, mess& m);
        friend std::ostream& operator<<(std::ostream& out, const mess& m);
}

std::istream& operator>>(std::istream& inp, mess& m)
{
    std::getline(inp, m.name);
    inp >> m.age;
    inp >> m.weight;
    inp >> m.height;
    return inp;
}

std::ostream& operator<<(std::ostream& out, const mess& m)
{
    out << m.name   << endl;
    out << m.age    << endl;
    out << m.weight << endl;
    out << m.height << endl;
    return out;
}

这简化了您的输入:

std::vector<mess> people;
mess              p;
while (input_file >> p)
{
  people.push_back(p);
}

您的输出如下:

for (unsigned int i = 0; i < people.size(); ++i)
{
  cout << people[i];
  cout << "\n";
}

答案 2 :(得分:0)

我会定义operator<<来写出你班级的一个对象。然后定义operator>>以读取您班级的对象。然后,您可以使用std::istream_iterator将值直接读入容器:

class M
{
    private:
        string name;
        float  age;
        float  weight;
        float  height;
    public:
        <STUFF>

    friend std::ostream& operator<<(std::ostream& s, M const& data)
    { 
        return s << data.age    << " " 
                 << data.weight << " " 
                 << data.height << " " 
                 // Put name on the edn because it may contain space.
                 // So we want to read it off using std::getline
                 << data.name   << "\n";
    }
    friend std::istream& operator>>(std::istream& s, M& data)
    { 
        s >> data.age >> data.wight >> data.height;
        std::getline(s, data.name);

        // Strip leading space (see output operator)
        data.name = data.name.substring(1);

        return s;
    }

};

然后在大多数容器中都很容易使用。

int main()
{
    std::ifstream  f("data");
    // OK.
    // A vector is not actually an array.
    // But you can use the same principle with a manual loop.
    // as std::istream_iterator is just a normal iterator.
    std::vector<M> data(std::istream_iterator<M>(f), std::istream_iterator<M>());
}