c - 当将输入从文件扫描到结构,然后保存更改时,为什么它总是写入第一行并删除其他所有内容?

标签 c file struct

因此,我正在为我的学校项目制作一个程序,该程序使用一些基本信息制作用户配置文件。此信息保存在以下结构中,但是当我尝试更改保存的配置文件中的一个参数时,比如年龄。我将配置文件加载到结构中,询问用户他们想要更改什么,然后进行更改。然后通过运行保存所有信息(现在已更改)的配置文件保护程序关闭

我遇到的问题是,当我更改结构中的某些内容然后尝试保存更改时,它会按照预期的方式保存更改,但是它会删除文件中的所有其他内容,这反过来会破坏加载程序,因为字符串不再存在,我认为

struct profile_info
{
char first_name[30];
char last_name[30];
char gender;
int age;
int height;
double weight;
}user_profile;

配置文件保护程序

/* this function til take the data inputted from the user and save to a .txt
file on the local pc */
void profile_saver(struct profile_info user_profile)
{
FILE *file_pointer;

file_pointer = fopen("test.txt", "w+");

fprintf(file_pointer, "%s\n%s\n %c\n%d\n%d\n%lf", user_profile.first_name, user_profile.last_name,
user_profile.gender, user_profile.age, user_profile.height, user_profile.weight);

fclose(file_pointer);
}

和配置文件加载器

/* this function will load the user profile if such a profile exists */
void user_profile_loader(struct profile_info user_profile)
{
FILE *file_pointer;
file_pointer = fopen("test.txt", "r");

fscanf(file_pointer, "%s", user_profile.first_name);

fscanf(file_pointer, "%s", user_profile.last_name);

fscanf(file_pointer, " %c", &(user_profile.gender));

fscanf(file_pointer, "%d", &(user_profile.age));

fscanf(file_pointer, "%d", &(user_profile.height));

fscanf(file_pointer, "%lf", &(user_profile.weight));

printf("Following profile has been loaded \n%s \n%s \n%c \n%d \n%d \n%lf\n", user_profile.first_name, user_profile.last_name,
user_profile.gender, user_profile.age, user_profile.height,     user_profile.weight);

fclose(file_pointer);
}

最后是转换器,一开始就解释过了

void profile_changer(struct profile_info user_profile)
{
int user_change_choice;

user_profile_loader(user_profile);

printf("What would you like to change? \nFirst name > 1 \nLast name > 2 \nGender > 3 \nAge > 4 \nHeight > 5 \nWeight > 6");
scanf("%d", &user_change_choice);

switch(user_change_choice)
    {
    case 1:
    printf("Please enter your new first name ");
    scanf("%s", user_profile.first_name);
    break;
    case 2:
    printf("Please enter your new last name ");
    scanf("%s", user_profile.last_name);
    break;
    case 3:
    printf("Please enter your new gender ");
    scanf(" %c", &(user_profile.gender));
    break;
    case 4:
    printf("Please enter your new age ");
    scanf("%d", &(user_profile.age));
    break;
    case 5:
    printf("Please enter your new heigt ");
    scanf("%d", &(user_profile.height));
    break;
    case 6:
    printf("Please enter your new weight ");
    scanf("%lf", &(user_profile.weight));
    }

profile_saver(user_profile);

}

最佳答案

我假设您已经在全局范围内定义了您的结构。当你写这个时:

struct profile_info
{
char first_name[30];
char last_name[30];
char gender;
int age;
int height;
double weight;
}user_profile;

这意味着你定义了一个新的结构体,并声明了一个全局变量user_profile,它是这个结构体的一个对象。当您调用 user_profile_loader(user_profile) 函数时,您正在制作 user_profile 变量的副本并将其发送到 user_profile_loader 函数。现在您正在接受新变量的值而不是 user_profile 变量,只是它们的名称相同,范围不同。当函数退出时,它不会更改 user_profile 变量,数据实际上不会加载到您的 user_profile 函数中,而是加载到另一个临时变量中。

当您调用 profile_saver(user_profile) 函数时,您再次传递 user_profile 变量以写入磁盘,但请记住,它从未加载过,并且没有赋值给它!因此它不会向磁盘写入任何内容。所以问题出在您的 user_profile_loader 函数上。

解决方案:

因为您的 user_profile 函数是全局的,您不需要将它传递给其他函数,因为它们事先可以直接访问该变量。将函数的定义更改为:

void profile_saver(){
/*code*/
}

void user_profile_loader(){
/*code*/
}

profile_changer() 函数中,进行以下更改:

void profile_changer()
{
int user_change_choice;
user_profile_loader();
printf("What would you like to change? \nFirst name > 1 \nLast name > 2 \nGender > 3 \nAge > 4 \nHeight > 5 \nWeight > 6");
scanf("%d", &user_change_choice);
switch(user_change_choice)
{
case 1:
printf("Please enter your new first name ");
scanf("%s", user_profile.first_name);
break;
case 2:
printf("Please enter your new last name ");
scanf("%s", user_profile.last_name);
break;
case 3:
printf("Please enter your new gender ");
scanf(" %c", &(user_profile.gender));
break;
case 4:
printf("Please enter your new age ");
scanf("%d", &(user_profile.age));
break;
case 5:
printf("Please enter your new heigt ");
scanf("%d", &(user_profile.height));
break;
case 6:
printf("Please enter your new weight ");
scanf("%lf", &(user_profile.weight));
}

profile_saver();
}

您的其他两个功能代码无需更改。我希望这能完成您的任务。

关于c - 当将输入从文件扫描到结构,然后保存更改时,为什么它总是写入第一行并删除其他所有内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33892008/

相关文章:

c++ - 生成大小不是 16 的倍数的加密数据

c++ - #ifdef 指令末尾的额外标记

Java 7 WatchService - 忽略同一事件的多次出现

C函数返回指向结构的指针

c - 段错误,大小为 4 的无效写入

c - 引用匿名结构本身

C 到 MIPS - 指令引用未定义 QTSpim

c - 使用 argv[] 时出现段错误

php - 为什么我尝试写入的文件是 "non-existing"?

php - 如何在不受内存限制的情况下在php中读取大文件