C 使用令牌从文件读取到不同的结构
我有两个不同的结构,其中C 使用令牌从文件读取到不同的结构,c,file,struct,token,C,File,Struct,Token,我有两个不同的结构,其中后面的是链表的一个节点 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;
后面的是链表的一个节点
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;
我必须通过读取以下文件来填充用户
结构:
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;
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);
}
}
用“;”分隔的内容用于填充用户
结构,用“!”分隔的内容用于填充后面的结构
注意:文件每行的“第二个”元素将是用户的名称,最多可以是25个字符,并且可以用空格分隔。例如,“来自寒冷的人”是一个有效的名字
我试着这样填充它们:
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;
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);
}
}
尽管“last_token”变量在每个循环中都保存了从文件读取的字符串的正确部分,但我无法找到填充两个结构的方法,因为sscanf
只填充用户
结构的一部分
任何帮助都将不胜感激。根据我设法解决问题的评论中的提示,将文件的内容更改为:
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
因此,我使用以下代码将信息提取到不同的结构中:
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);
}
}
我必须为每行重新运行文件字符串2次,因为有3种类型的令牌,;[(
@melpomene这只是为了节省空间,避免问题变得更大,如果需要的话,我可以更改…请做…@user3121023可能是这个%26[^\n]会更好吗?@user3121023我需要选择可以用空格分隔的用户名,我永远不知道它会有多长。我认为换行符是一个足够的结尾分隔符。为什么不使用分号来分隔每个字段呢?zsq4r;Pseu Donym;3;1;2;zero7;2;true
-尽管我看到你在en有一个三元组的列表d、 可能采用JSON中的一个叶子:zsq4r;Pseu Donym;3;1;2[zero7;2;true]
,其中可以使用[]
以外的其他字符来包围数据,以及一组[]
per triple。基本上,您可以设计格式,以便使用您希望用于解析的工具轻松解析。您可能应该阅读整行内容,然后使用或临时解析。