这是一个完整的示例,可以满足您的要求。
你没有要求但它仍然要求的东西:
- 它使用异常来报告数据文件格式错误,以便
GetModelForUser() 可以简单地返回一个对象(而不是布尔值或类似的东西)。
- 它使用模板函数将行拆分为字段。这确实是原始问题的核心,因此有点不幸的是,这可能过于复杂。但这里将其设为模板函数的想法是将字符串拆分为字段与选择数据结构来表示结果的关注点分开。
/* Parses a file of user data.
* The data file is of this format:
* username:email-address:pincode
*
* The pincode field is actually one-way-encrypted with a secret salt
* in order to avoid catastrophic loss of customer data when the file
* or a backup tape is lost/leaked/compromised. However, this code
* simply treats it as an opaque value.
*
* Internationalisation: this code assumes that the data file is
* encoded in the execution character set, whatever that is. This
* means that updates to the file must first transcode the
* username/mail-address/pincode data into the execution character
* set.
*/
#include
#include
#include
#include
#include
#include
const char* MODEL_DATA_FILE_NAME = "test.txt";
// 这个东西真的应该放在头文件中。
类 UserUnknown : public std::exception { };
类 ModelDataIsMissing : public std::exception { };
类 InvalidModelData : 公共 std::exception { }; // base: 不要直接抛出这个。
类 ModelDataBlankLine :公共 InvalidModelData { };
类 ModelDataEmptyUsername:公共 InvalidModelData { };
类 ModelDataWrongNumberOfFields : public InvalidModelData { };
类用户模型 {
标准::字符串用户名_;
std::string email_address_;
std::string pincode_;
公开:
UserModel(std::string username, std::string email_address, std::string pincode)
:用户名_(用户名),电子邮件地址_(电子邮件地址),密码_(密码){
}
UserModel(const UserModel& 其他)
:用户名_(其他。用户名_),
email_address_(other.email_address_),
pincode_(other.pincode_) {
}
std::string GetUsername() const { return username_; }
std::string GetEmailAddress() const { return email_address_; }
std::string GetPincode() const { return pincode_; }
};
UserModel GetUserModelForUser(const std::string& username)
throw (InvalidModelData, UserUnknown, ModelDataIsMissing);
// 这东西就是实现。
namespace { // 使用空命名空间来实现模块化。
模板无效SplitStringOnSeparator(
std::string 输入、字符分隔符、ForwardIterator 输出)
{
std::string::const_iterator field_start, pos;
bool in_field = false;
for (pos = input.begin(); pos != input.end(); ++pos) {
如果(!in_field){
field_start = 位置;
in_field =真;
}
if (*pos == 分隔符) {
*输出++ = std::string(field_start, pos);
in_field = 假;
}
}
if (field_start != input.begin()) {
*输出++ = std::string(field_start, pos);
}
}
}
// 返回指定用户的 UserModel 实例。
//
// 每次程序调用不要多次调用它,因为
// 你最终会得到二次性能。而是修改此代码
// 返回从用户名到模型数据的映射。
UserModel GetUserModelForUser(const std::string& username)
抛出(InvalidModelData、UserUnknown、ModelDataIsMissing)
{
std::string 行;
std::ifstream in(MODEL_DATA_FILE_NAME);
如果(!在){
抛出 ModelDataIsMissing();
}
while (std::getline(in, line)) {
std::vector<std::string> fields;
SplitStringOnSeparator(line, ':', std::back_inserter(fields));
if (fields.size() == 0) {
throw ModelDataBlankLine();
} else if (fields.size() != 3) {
throw ModelDataWrongNumberOfFields();
} else if (fields[0].empty()) {
throw ModelDataEmptyUsername();
} else if (fields[0] == username) {
return UserModel(fields[0], fields[1], fields[2]);
}
// We don't diagnose duplicate usernames in the file.
}
throw UserUnknown();
}
命名空间{
布尔示例(const char *arg)
{
常量 std::string 用户名(arg);
尝试
{
用户模型模块(GetUserModelForUser(用户名));
std::cout
int main (int argc, char *argv[])
{
int我,returnval=0;
对于 (i = 1; i
/* 局部变量:/
/ c-file-style: "stroustrup" /
/ 结束:*/