开发者

Read/write data then separate data

I am a newbie in C++. I am doing a C++ sign up form where I keep all the user datas in a text file named user.txt with formats like

name|password|address|postal|phone

Each user record will occupy one line.

So my first question how can I do this nicely in C++

As for the reading part, my main problem is how to separate the data by splitting "|" then put the records in a user array. So when I do a login function I can loop through the array to match users.

My current code for reading is

string User::readUser(){
    ifstream fin("user.txt");
    string line;
    while(getline(line,fin)){
        string name, password, address; int postal, phone;//put the records into a 2 dimention array
   开发者_高级运维 }
    //return array
}


Check out this answer.

In your case, the fields will be appended to the vector<string> in order, so you can access them directly from it. First position would correspond to the name, second to the password and so on.

Here's an example:

// The elements should be in this order: name, password, address, postal, phone
vector<string> v = split(line, '|');
string name = v[0], password = v[1], address = v[2];

As for your second question, you could create a structure or class that describes the user:

struct User {

    // Using type string for all fields for convenience.
    string name, password, address, postal, phone;

    User(string n, string pw, string a, string p, string ph): name(n),
                                                              password(pw),
                                                              address(a),
                                                              postal(p),
                                                              phone(ph) {}

};

vector<User> uv;

// ...

// Split string, create user instance and append it to the user list
vector<string> v = split(line, '|');
uv.push_back(User(v[0], v[1], v[2], v[3], v[4]));

To iterate over the User vector:

for (int i = 0; i < uv.size(); ++i) {
    if (uv[i].name == "John") {
        // Process John...
    }
}


Some time ago I wrote an answer with a C++ sscanf replacement. It fits perfectly for your case:

std::vector<boost::any> user_data;
sscanf(line, "%s|%s|%s|%i|%i", user_data);

Now constructing a User (a struct like in Matheus Moreira's answer) is very simple:

User(boost::any_cast<std::string>(user_data[0]), // name
     boost::any_cast<std::string>(user_data[1]), // password
     boost::any_cast<std::string>(user_data[2]), // address
     boost::any_cast<int>(user_data[3]),  // postal
     boost::any_cast<int>(user_data[4])); // phone

This requires boost's any and lexical_cast.


The obvious solution would be to use boost::regex on each line: this will do input format checking as well as separate out the fields. Something like:

while ( getline( line, fin ) ) {
    static boost::regex const pattern(
        "\\([^|]+\\)\\|\\([^|]+\\)|\\([^|]+\\)|\\([^|]+\\)|\\([^|]+\\)" );
    boost::smatch match;
    if ( !regex_match( line, match, pattern ) ) {
        //  Error handling...
    } else {
        // match[1] is name, match[2] is password, etc.
    }
}

More complex matching patterns are possible, requiring e.g. postal and phone to be numeric. You could also easily modify it to allow leading and trailing white space as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜