我有一个csv excel文件,例如学生姓名,身份证,分数,班主任姓名等。
如果我提供了学生的姓名,我想提取学生的数据,因为我需要将其与仅在第一栏中提供的数据进行比较。
所以我已经将数据存储到2d数组中。当我尝试提取第一列时。我不行
这是我的代码。
答案 0 :(得分:0)
解决方案是将数据放入结构中,然后覆盖此结构的提取器和插入器运算符。这使您可以轻松使用std::algorithm
。
在C ++中,您的文件结构称为CSV(逗号分隔值)。并且,阅读此内容是一项标准任务。首先,阅读整行,然后使用给定的定界符提取该字符串的标记。 “拆分”也称为“令牌化”,C ++为此目的提供了专用功能:
std::sregex_token_iterator
。此构造是一个迭代器。用于遍历字符串,因此称为“ sregex”。开始部分定义了我们将在什么输入范围上进行操作,然后在输入字符串中有一个std :: regex表示应该匹配的内容或不应该匹配的内容。匹配策略的类型由最后一个参数给出。
我们将结合使用std::copy
和std::back_inserter
来将数据复制到目标向量。
可以使用std:istream_iterator
来读取while文件。
这样一来,只需一行即可完成整个文件的读取和处理:
std::vector roster(std::istream_iterator<Student>(ifs), {});
这将变量“名册”定义为std :: vector,并使用std :: vector的所谓范围构造函数。请注意:我使用的是C ++ 17,可以不使用模板参数定义std :: vector。编译器可以从给定的函数参数中推导出自变量。此功能称为CTAD(“类模板参数推导”)。
此外,您可以看到我没有明确使用“ end()”迭代器。
此迭代器将使用正确的类型从空括号括起来的初始化程序列表构造,因为由于std :: vector构造函数要求与第一个参数的类型相同,因此会推断出它。 >
那么显示第一列就是一个简单的循环迭代。
请参见以下简单示例:
#include <iostream>
#include <fstream>
#include <regex>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
std::regex delimiter{ "," };
struct Student {
// Any kind of student data. Can be converted later
std::vector<std::string> data{};
// Overwrite extractor operator
friend std::istream& operator >> (std::istream& is, Student& s) {
if (std::string line{}; std::getline(is, line)) {
s.data.clear();
std::copy(std::sregex_token_iterator(line.begin(), line.end(), delimiter, -1), {}, std::back_inserter(s.data));
}
return is;
}
// Overwrite inserter
friend std::ostream& operator << (std::ostream& os, const Student& s) {
std::copy(s.data.begin(), s.data.end(), std::ostream_iterator<std::string>(os, "\n"));
return os;
}
};
int main() {
// Open file and check if OK
if (std::ifstream ifs("r:\\unit_db.csv"); ifs) {
// Read all lines from file, split them and put them in this vector
std::vector roster(std::istream_iterator<Student>(ifs), {});
// Show all data on screen
std::copy(roster.begin(), roster.end(), std::ostream_iterator<Student>(std::cout, "\n"));
// Show first column
for (const Student& s : roster)
std::cout << "\n" << s.data[0];
}
return 0;
}
您还可以使用以下替代方法main
int main() {
// Open file and check if OK
if (std::ifstream ifs("r:\\unit_db.csv"); ifs) {
const std::string name("John");
if (auto search = std::find_if(std::istream_iterator<Student>(ifs), std::istream_iterator<Student>(),
[&name](const Student& s) { return s.data[0] == name; }); search != std::istream_iterator<Student>()) {
std::cout << "Searched for '" << name << "' and found: " << *search << "\n";
}
else
std::cout << "*** Error: '" << name << "' not found.\n";
}
return 0;
}
但是也许最好先阅读所有内容然后搜索。
当然还有许多其他可能的解决方案。