c-传递结构中成员的引用以对其进行修改



我正在为一个大学项目做一个程序。目前,我正在进行用户配置,以便能够更改密码和用户名。我在想一种方法,对两个过程都使用一个函数,而不是创建两个单独的函数。

我的目标是传递对保存用户数据的结构的引用,以及对我要编辑的结构的相应成员的引用,两者都是char[64]。因此,在我编辑成员后,我可以用更新的数据重写文件中的整行。


void change_user_data(char *input, struct user ***logged_user,
char *data_to_alter, FILE **user_registry) {
// making sure the returned input is valid.
if (strcmp(input, "..."))
return;
struct user find_user;
fseek(*user_registry, 0, SEEK_SET);
while (!feof(*user_registry)) {
fread(&find_user, sizeof(struct user), 1, *user_registry);
if (0 != strcmp(find_user.user_name, (**logged_user)->user_name))
continue;
strcpy(data_to_alter, input);
fseek(*user_registry, 0, SEEK_CUR - 1);
fwrite((**logged_user), sizeof(struct user), 1, *user_registry);
break;
}
return;
}

这是一个应该同时处理结构和文件更改的函数。


change_user_data(change_password(input), &logged_user, (*logged_user)->password, &user_id);

这是我试图通过的论点。

没有错误消息,但结构或文件都没有任何更改。我想现在发生的事情是,它只是创建了一个成员的副本,我试图改变我通过成员的方式,但都没有成功。

最小再现性示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 64
struct user {
char user_name[MAXLEN];
char password[MAXLEN];
};
void placeholder_function(struct user *logged_user);
void change_user_data(char *input, struct user **logged_user,
char *data_to_alter, FILE **user_registry);
int main() {
struct user logged_user;
placeholder_function(&logged_user);
return 0;
}
void placeholder_function(struct user *logged_user) {
FILE *user_registry;
if (!(user_registry = fopen("user_registry.bin", "w+b"))) {
printf("Couldn't open filen");
exit(1);
}
strcpy(logged_user->user_name, "Admin");
strcpy(logged_user->password, "Admin");
fseek(user_registry, 0, SEEK_SET);
fwrite(logged_user, sizeof(struct user), 1, user_registry);

// expected output: Admin Admin
printf("%s %sn", logged_user->user_name, logged_user->password);
// rest of program here...
change_user_data("1234", &logged_user, logged_user->password,
&user_registry);
printf("%s %sn", logged_user->user_name, logged_user->password);
// wanted output: Admin 1234
}
void change_user_data(char *input, struct user **logged_user,
char *data_to_alter, FILE **user_registry) {
struct user find_user;
fseek(*user_registry, 0, SEEK_SET);
while (!feof(*user_registry)) {
fread(&find_user, sizeof(struct user), 1, *user_registry);
if (0 != strcmp(find_user.user_name, (*logged_user)->user_name))
continue;
strcpy(data_to_alter, input);
fseek(*user_registry, 0, SEEK_CUR - 1);
fwrite((*logged_user), sizeof(struct user), 1, *user_registry);
break;
}
}

我不能100%确定您的具体示例中出了什么问题。

但您只需要传递结构的地址或元素的地址,而不需要同时传递这两个地址。在这种情况下:

struct user ***logged_user

然后你可以用修改元素

strcpy((**logged_user)->password, input);

现在,如果您只关心这个函数中的密码而不关心用户名,那么您可以只传递一个指向密码而不指向容器结构的指针。但这是你的选择。

现在,这个代码还有其他一些问题。您需要确保来自输入的复制不会导致(**logged_user(中的缓冲区溢出->暗语您可以通过确保输入足够小来实现这一点,也可以使用strncpy函数。确保目的地变为空终止,通常使用(**logger_user)->password[pass_len - 1] = ''

这一行fseek(*user_registry, 0, SEEK_CUR - 1);

奇怪的是,SEEK_CUR-1将评估为SEEK_SET,我怀疑你是否想这样做。

好吧,现在可以工作了。刚刚将结构的编辑更改为函数change_password()。并编辑了我想要编辑的确切成员。


bool change_password(char *new_password, struct user ***logged_user) {
char repeat_password[MAXLEN];
system(CLEAR);
printf("nInput the new password: ");
trim_line(get_input(new_password, MAXLEN));
printf("nRepeat the new password: ");
trim_line(get_input(repeat_password, MAXLEN));
if (0 != strcmp(new_password, repeat_password)) {
fprintf(stderr, "nNew password mismatch!n");
printf(KEY_PRESS);
free_buffer();
return false;
}
strcpy((**logged_user)->data.password, new_password);
return true;
}

之后,我将结构传递给change_user_data()函数并完成

void change_user_data(bool is_valid, struct user ***logged_user,
FILE **user_registry) {
// making sure the returned input is valid.
if (!is_valid)
return;
struct user find_user;
fseek(*user_registry, 0, SEEK_SET);
while (!feof(*user_registry)) {
fread(&find_user, sizeof(struct user), 1, *user_registry);
if (0 != strcmp(find_user.data.user_name, (**logged_user)->data.user_name))
continue;
fseek(*user_registry, 0, SEEK_CUR - 1);
fwrite((**logged_user), sizeof(struct user), 1, *user_registry);
break;
}
return;
}

我仍然需要实现别人给我的其他建议,比如不要使用feof((,并将自己正确地放在文件中,但这只是一个开始。

最新更新