您可以逐个字符地读取文件。那么
- 先等一开门”
- 如果到达,更改模式并
- 将字符复制到临时名称字符串中
- 如果我们检测到关闭“,我们将名称复制到我们的名称向量并从头开始
信息。由于我们不知道名称的数量,我们使用动态增长的“数组”,即所谓的std::vector
请查看许多可能的示例之一:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
// Open a file and check, if it is open
if (std::ifstream fileStream("names.txt"); fileStream) {
// Here we will store all names
std::vector<std::string> names{};
// This is for one name, we will build it character by character
std::string name{};
// We will read the file character wise
char c{};
// We build a little state machine. Either we wait for a starting " or we copy data
bool copyCharacter{ false };
// Read all characters from file. We could have also used while (fileStream.get(c))
while (fileStream >> std::noskipws >> c) {
// Are we waiting for the opening " or not
if (!copyCharacter) {
// We are waiting for the opening ". Check if we have read one.
if (c == '\"') {
// We read an opening ". In the next step, we will copy the characters into the name
copyCharacter = true;
}
}
else {
// We are in copy mode. This will end with a closing ". Check, if we read one complete name
if (c == '\"') {
// We found a closing " after a name. Therefore we stop this mode and wait for an opening " again
copyCharacter = false;
// We found a complete name. Add it to our target names
names.push_back(std::move(name));
// Temporary name will be reset, to be ready to read next name
name = {};
}
else {
// Copy mode. Add character to name
name += c;
}
}
}
// Show debug output
std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
for (const std::string name : names) std::cout << name << '\n';
}
else {
std::cerr << "\n\n***Error: Could not open source file\n";
}
return 0;
}
还有第二种可能。您可以使用逗号作为分隔符。有个函数std::getline
所以,首先按名称读取字符串名称,然后删除 ",然后将名称列表添加到我们的名称向量中:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
// Open a file and check, if it is open
if (std::ifstream fileStream("names.txt"); fileStream) {
// Here we will store all names
std::vector<std::string> names{};
// This is for one name, including quotes
std::string name{};
// Read a complete name, until the next comma, include quotes
while (std::getline(fileStream, name, ',')) {
// Get the substring of name, without the quotes
names.emplace_back(name.substr(1, name.size() - 2));
}
// Show debug output
std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
for (const std::string name : names) std::cout << name << '\n';
}
else {
std::cerr << "\n\n***Error: Could not open source file\n";
}
return 0;
}
而最高级和最复杂的解决方案是使用std::regex
但现在这可能太多了。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <regex>
#include <algorithm>
std::regex re{R"((\w+))"};
int main() {
// Open a file and check, if it is open
if (std::ifstream fileStream("names.txt"); fileStream) {
// Here we will store all names
std::vector<std::string> names{};
// Read a complete line with all names in it
for (std::string line{}; std::getline(fileStream, line);) {
// Split the line in single names and copy the name to our names vector
std::copy(std::sregex_token_iterator(line.begin(), line.end(), re), {}, std::back_inserter(names));
}
// Show debug output
std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
for (const std::string name : names) std::cout << name << '\n';
}
else {
std::cerr << "\n\n***Error: Could not open source file\n";
}
return 0;
}