简体   繁体   中英

reading from a file using tokens to different structs

I have two different structs, where following is a node of a linked list

typedef struct following{
    char nick[6];
    int last_message;
    bool first_time;
    struct following *next;
}following;

typedef struct user{                     
    char nick[6];
    char name[26];
    int n_messages;
    int n_following;
    int n_followers;
    following *arr_following;
    following *arr_unfollowed;
}user;

I have to fill the user struct by reading from a file like this:

zsq4r Pseu Donym 3 1 2;zero7 2 true!
zero7 James Bond 4 3 3;zsq4r 3 true!zero7 4 false!MrPym 1 true!
MrPym A Perfect Spy 1 3 1;zsq4r 3 true!zero7 4 true!AlecS 1 true!
AlecS He Who Came from the Cold 1 0 1;

The content delimited by the ";" is to fill the user struct and the content delimited by "!" to fill the following struct.

Note: the "second" element of each line of the file will be the name of the user, which can go up to 25 chars and can be separated by white space. For example, "He Who Came from the Cold" is a valid name.

I tried to fill them like this:

void read_from_file(hashtable *active_users, FILE *fp_active){
    const char *delimiter1 = "!";
    const char *delimiter2 = ";";
    char *last_token;
    char buffer[1540];
    while(fgets(buffer, 1540, fp_active)) {
        user *new_user = malloc(sizeof(user));
        last_token = strtok( buffer, delimiter2);
        while( last_token != NULL ){
            sscanf(last_token,"%s %[^\n] %d %d %d", new_user->nick, new_user->name, &new_user->n_messages, &new_user->n_following,
                   &new_user->n_followers);
            last_token = strtok( NULL, delimiter1);
        }
        insert(active_users, new_user);
    }
}

Although the "last_token" variable is holding the correct part of the string read from the file at each loop, I can't find away to fill both structs, since sscanf is only filling part of the user struct.

Any help would be appreciated.

Based on the tips from the comments i manage to solve my problem, changing the aspect of the file to this:

zero7;James Bond;2;1;0[MrPym;1;true](zero7;0;false)
MrPym;A Perfect Spy;1;0;1
zsq4r;Pseu Donym;3;1;2[zero7;2;true]
zero7;James Bond;4;3;3[zsq4r;3;true][zero7;3;false][MrPym;1;true]
MrPym;A Perfect Spy;1;3;1[zsq4r;3;true][zero7;4;true][AlecS;1;true]
AlecS;He Who Came from the Cold;1;0;1

And from that i used the following code to extract the information to the different structs:

void read_from_file(hashtable *active_users, hashtable *inactive_users, FILE *fp_active, FILE *fp_inactive){
    char m_bool[6];
    char *first_token;
    char *last_token;
    char buffer[1540];
    char buffer2[1540];
    while(fgets(buffer, 1540, fp_active)) {
        strcpy(buffer2, buffer);
        user *new_user = malloc(sizeof(user));
        new_user->arr_following = NULL;
        new_user->arr_unfollowed = NULL;
        last_token = strtok( buffer, "[");
        sscanf(last_token,"%[^;]; %[^;]; %d; %d; %d", new_user->nick, new_user->name, &new_user->n_messages, &new_user->n_following,
               &new_user->n_followers);
        last_token = strtok( NULL, "[");
        while(last_token != NULL){
            following *tmp_following = malloc(sizeof(following));
            sscanf(last_token," %[^;]; %d; %5s", tmp_following->nick, &tmp_following->last_message, m_bool);
            if(strcmp(m_bool, "true]") == 0)
                add(&new_user->arr_following, tmp_following->nick, tmp_following->last_message, true);
            else
                add(&new_user->arr_following, tmp_following->nick, tmp_following->last_message, false);
            last_token = strtok( NULL, "[");
        }
        first_token = strtok( buffer2, ")");
        while(first_token != NULL && strcmp(first_token, buffer2) != 0){
            following *tmp_following = malloc(sizeof(following));
            sscanf(first_token," %[^;]; %d; %5s", tmp_following->nick, &tmp_following->last_message, m_bool);
            if(strcmp(m_bool, "true]") == 0)
                add(&new_user->arr_unfollowed, tmp_following->nick, tmp_following->last_message, true);
            else
                add(&new_user->arr_unfollowed, tmp_following->nick, tmp_following->last_message, false);
            first_token = strtok( NULL, "(");
        }
        insert2(active_users, new_user);
    }
}

I had to re-run the file string 2 times for each line because there was 3 types of tokens, ; [ ( ; [ (

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM