[英]Passing a reference of a member in a struct to modify it
我正在为一个大学项目做一个程序。 目前我正在做用户配置,以便能够同时更改密码和用户名。 我正在考虑一种方法,对两个进程使用单个 function 而不是创建两个单独的进程。
我的目标是传递对保存用户数据的结构的引用,以及对我要编辑的结构的相应成员的引用,两者都是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;
}
这是 function 应该处理结构和文件的更改。
change_user_data(change_password(input), &logged_user, (*logged_user)->password, &user_id);
这是我通过 arguments 的尝试。
没有错误消息,但结构或文件都没有任何更改。 我想正在发生的事情是它只是创建了成员的副本,我试图改变我传递成员的方式,但它们都没有奏效。
最小可复制示例:
#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 file\n");
exit(1);
}
strcpy(logged_user->user_name, "Admin\0");
strcpy(logged_user->password, "Admin\0");
fseek(user_registry, 0, SEEK_SET);
fwrite(logged_user, sizeof(struct user), 1, user_registry);
// expected output: Admin Admin
printf("%s %s\n", logged_user->user_name, logged_user->password);
// rest of program here...
change_user_data("1234\0", &logged_user, logged_user->password,
&user_registry);
printf("%s %s\n", 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);
现在,如果您只关心密码而不关心此 function 中的用户名,您可以只传递一个指向密码的指针,而不是容器结构。 但这是你的选择。
现在,此代码还有其他一些问题。 您需要确保输入的副本不会导致 (**logged_user)->password 中的缓冲区溢出。 您可以通过确保输入足够小来做到这一点,或者使用 strncpy function 代替。 确保目标变为 null 终止,通常使用(**logger_user)->password[pass_len - 1] = '\0'
这一行fseek(*user_registry, 0, SEEK_CUR - 1);
很奇怪,SEEK_CUR - 1 将评估为 SEEK_SET,我怀疑你想要这样做。
嗯,现在可以了。 刚刚将结构的编辑更改为 function 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()
function 并完成
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(),并将自己正确放置在文件中,但这是一个开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.