我正在尝试读取包含个人信息的文件。每行包含一个人的数据,可以这样说:
First(s) Last ID SSN
Peter Barker 1234 5678
James Herbert Bond 007 999
Barack Hussein Obama 2007 14165
所以我想使用std::copy
读取每一行并将其复制到(std::vector<Person>
)中,如下所示:
struct Person
{
std::string firstName_s;
std::string lastName;
int ID;
int SSD;
}
我认为为此重载提取运算符会很方便:
std::istringstream& operator>>(std::istringstream& in, struct Person& person)
{
struct Person tmp;
in >> tmp.firstName_s
>> tmp.lastName
>> tmp.ID
>> tmp.SSN;
person = std::move(tmp);
return in;
}
但是,我遇到的问题是我不知道该人将拥有多少个名字。
我曾想过将全名读成一个字符串,直到遇到一个数字,然后他们将姓氏从包含名字的字符串中分离出来,这很好用,但看起来很丑。如果有人有更好的建议,或者我可以看的链接,但我似乎自己找不到东西,那将是很棒的!谢谢。
[如果您有可变长的行(就字数而言),您可以简单地读取整行并从右侧进行处理,或者缓存所有字并使用偏移量。下面的示例执行后一个。
int to_int(std::string_view str)
{
int val = 0;
std::from_chars(str.data(), str.data() + str.size(), val);
return val;
}
std::istream& operator>>(std::istream& in, Person& person)
{
std::string line;
std::vector<std::string_view> words;
// read whole line
if (std::getline(in, line))
{
// split line into words
std::string_view text = line;
for (auto pos = text.find_first_of(' '); pos != std::string_view::npos; pos = text.find_first_of(' '))
{
words.push_back(text.substr(0, pos));
text.remove_prefix(pos + 1);
}
words.push_back(text);
// join first names
std::stringstream ss;
for (std::size_t i = 0; i < words.size() - 3; i++)
ss << ' ' << words[i];
person.firstName_s = ss.str().substr(1);
person.lastName = words[words.size() - 3];
person.ID = to_int(words[words.size() - 2]);
person.SSN = to_int(words[words.size() - 1]);
}
return in;
}
我认为代码是不言自明的。 Here是一个完整的示例。