繁体   English   中英

在结构中传递成员的引用以修改它

[英]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.

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