【问题标题】:C++ read line to class vectorC++ 读取行到类向量
【发布时间】:2018-10-21 16:00:26
【问题描述】:

我有下一个名为“Contact”的 c++ 类:

class Contact
{
private:
    std::string contactName;
    double subscriptionPrice;
    int minutesIncluded;

public:
    Contact(const std::string &contactName, double subscriptionPrice,
            int minutesIncluded) : contactName(contactName), subscriptionPrice(subscriptionPrice), minutesIncluded(minutesIncluded)) {}
    Contact() {

    }

    ...gettetrs and setters
}

我有一个包含一个或多个联系人的文本文件,格式为:

asd,1.00000,1

在主要方法中,我有在此文本文件中正确添加联系人向量的方法。问题是当我尝试从中读取时。我的目标是将文本文件转换为联系人向量。我使用的方法是下一个:

void phonebook_load(vector<Contact> &contacts)
{
    string line;
    ifstream phonebook_file;
    vector<std::string> lines;
    phonebook_file.open(phonebook_filename);
    if(!phonebook_file.is_open())
        cout << "Phonebook file could not be openned !!!" << endl;
    else
    {
        while (phonebook_file.good())
        {
            for (string line; getline(phonebook_file, line, ','); )
                lines.push_back(line);
        }
        phonebook_file.close();
    }
}

我有两个选择:

  1. 逐行阅读(不能用“,”分割)
  2. 按“,”分割,在新行上打印联系人的每个属性,我不知道如何从那里处理它。

为了逐行读取文件并将其正确转换为vector&lt;Contact&gt;,我应该在我的方法中进行哪些更改

【问题讨论】:

  • fscanf(ww,"%s,%f,%d%*c",...) ;

标签: c++ vector concatenation ofstream


【解决方案1】:

为您的类型提供流提取和流插入运算符:

#include <string>
#include <vector>
#include <iterator>
#include <fstream>
#include <iostream>


class Contact
{
private:
    std::string contactName;
    double subscriptionPrice;
    int minutesIncluded;

public:
    Contact() {}
    Contact(const std::string &contactName, double subscriptionPrice, int minutesIncluded)
    : contactName       { contactName },
      subscriptionPrice { subscriptionPrice },
      minutesIncluded   { minutesIncluded }
    {}

    // declare the stream extraction and stream insertion operators as firends
    // of your class to give them direct access to members without the need for
    // getter and setter functions.
    friend std::istream& operator>>(std::istream &is, Contact &contact);
    friend std::ostream& operator<<(std::ostream &os, Contact const &contact);
};

std::istream& operator>>(std::istream &is, Contact &contact)
{
    std::string contact_name;
    if (!std::getline(is, contact_name, ','))  // use getline with a delimiter
        return is;                             // to allow whitespace in names
                                               // which >> doesn't
    char seperator;
    double subscription_price;
    int minutes_included;
    if (!(is >> subscription_price >> seperator >> minutes_included) || seperator != ',') {     
        is.setstate(std::ios::failbit);
        return is;
    }

    contact = Contact{ contact_name, subscription_price, minutes_included };
    return is;
}

std::ostream& operator<<(std::ostream &os, Contact const &contact)
{
    os << contact.contactName << ", " << std::fixed << contact.subscriptionPrice
       << ", " << contact.minutesIncluded;
    return os;
}

int main()
{
    std::ifstream is{ "test.txt" };
    std::vector<Contact> contacts{ std::istream_iterator<Contact>{ is },
                                   std::istream_iterator<Contact>{} };

    for (auto const &c : contacts)
        std::cout << c << '\n';
}

【讨论】:

  • @TeodorKolev 如图所示,要读取的文件的std::ifstream
  • @TeodorKolev 请看我回答中示例的最后几行。有一个std::ifstream is{ "test.txt" }; 被定义。替换您自己的文件名并将is 传递给用于构造vector 的第一个std::istream_iterator 的构造函数。
  • 对不起,我看到了,但是没用,我正在调试中
  • 抱歉,这没有返回正确的数据。如果 (!(is >> subscription_price >> 分隔符 >> minutes_included) || 分隔符 != ',') { is.setstate(std::ios::failbit);回报是; }
  • @TeodorKolev 然后请编辑您的问题以包含输入文件和预期输出以及您正在使用的代码。
猜你喜欢
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
相关资源
最近更新 更多