无法将.csv文件读入表示向量结构的类中

时间:2016-12-24 03:41:00

标签: c++ sorting csv vector

我无法将30行.csv文件的内容读入以下结构:

class Entry {
public:
    std::string GID;
    std::string DName;
    std::string Phone;
    std::string POC;
    std::string Item;
    std::string Category;
    double amount;
};

我希望能够创建一个能够读取被称为“Donations.csv”的csv文件并删除逗号的函数,因为我想创建一个可能是这样的向量:std::vector<Entry> entries;以便我可以排序基于向量中的任何元素的多个项目。所以例如说我想按DName排序,代码看起来像这样:

// sort by DName
std::sort(entries.begin(), entries.end(), [](const Entry& a, const Entry& b) {
    return a.DName.compare(b.DName) < 0;
});

我被告知不要使用多个向量,因为这不安全和有效,但如果它可以帮助某人,这是如何将csv文件读入多个向量:
公平警告,使用EOF控制器错误,请参阅HERE
虽然,这段代码可以正常使用,我已亲自测试过 - 在.csv文件上多次。

int main()
{
ifstream inFile;                    // Input file handler
ofstream outFile;                   // Output file handler

vector<string> GID;                 // Vector holding Gift ID
vector<string> DName;               // Vector holding Donor Name
vector<string> Phone;               // Vector holding Phone Number
vector<string> POC;                 // Vector holding point of contact
vector<string> Item;                // Vector holding item donated 
vector<string> Category;            // Vector holding type of item donated
vector<double> amount;              // Vector holding amount of donated items

int Input;                          // User selection choice from menu

// opening data file
inFile.open("Donations.csv");
if (!inFile)                        // If statement to check for file erroe
{
    cout << "Input file did not open. Program will exit." << endl;      // Does not compute!
    exit(0);
}

// reading contents
string str;                         // temp string to hold parse comma
double temp;                        // temp double to hold null spaces for atoi function/strtod

getline(inFile, str, ',');          // read first GID string outside of loop so that we
                                    // won't accidentally reach the end of the file in the MIDDLE of the loop

while (!inFile.eof())               // end of file not reached
{
    GID.push_back(str);
    getline(inFile, str, ',');      // get the contents of the line until a comma is encountered and push it into the necessary vector
    DName.push_back(str);
    getline(inFile, str, ',');
    Phone.push_back(str);
    getline(inFile, str, ',');
    POC.push_back(str);
    getline(inFile, str, ',');
    Item.push_back(str);
    getline(inFile, str, ',');
    Category.push_back(str);
    getline(inFile, str, '\n');     // get until the end of the line but split for parsing

    // convert string to double using strtod and c_str
    temp = strtod(str.c_str(), NULL);
    // now push double onto vector
    amount.push_back(temp);
    getline(inFile, str, ',');      // read in GID here instead of the top.  If we are at the end
                                    // of the file, it won't work and end-of-file flag will be set which is what we want.
}
inFile.close();
}

1 个答案:

答案 0 :(得分:-1)

添加此方法:

friend std::istream& operator>>(std::istream& input, Entry& e);

到您的Entry结构。

将此添加到您的源代码:

std::istream&
operator>>(std::istream& input, Entry& e)
{
    input >> e.GID;
    input >> e.Dname;
    //.. input other members
    return input;
}

将容器更改为:

std::vector<Entry> database;

您的输入循环将如下所示:

Entry e;
while (my_data_file >> e)
{
  database.push_back(e);
}

您可能还想在互联网上搜索&#34; stackoverflow c ++ read file struct&#34;更多例子。

总之,创建一个结构或类来为记录建模 重载运算符&gt;&gt;阅读记录。
使用结构的std::vector,而不是每个数据成员的向量 如果你认真对待数据库,那就用一个;不要重写自己的。

编辑1:排序
为了使排序更容易,请重载>运算符:

struct Entry
{
  //...
  bool operator<(const Entry& other) const
  {
    // add comparison functionality, example:
    return GID < other.GID;
  }
}

现在,您可以使用以下方法对数据库进行排序:

std::sort(database.begin(), database.end());

编辑2:其他排序
要使用不同的标准订购容器,您可以创建排序函数并将它们传递给std::sort函数:

bool Order_By_Dname(const Entry& e1, const Entry& e2)
{
  return e1.Dname < e2.Dname;
}

您的排序变为:

std::sort(database.begin(), database.end(), Order_By_Dname);