Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux环境中用C编写文件时出现的问题_C_Linux - Fatal编程技术网

在Linux环境中用C编写文件时出现的问题

在Linux环境中用C编写文件时出现的问题,c,linux,C,Linux,我正试图为大学里的一个项目建立一个健身计划。 我们是在Linux环境中用C语言实现的。 我读取文件时没有问题,但是当我尝试更新文件时,如果我打印到文件末尾带有“\n”,它会在两行之间插入双回车。如果我没有,它会把所有的数据放在一行 我该怎么办 i、 我添加了一个从文件读取和更新文件的函数示例 Employees** Init_Gym_emp(Employees** emp, int* num) { FILE* f = fopen("Gym Employees.txt", "r");

我正试图为大学里的一个项目建立一个健身计划。 我们是在Linux环境中用C语言实现的。 我读取文件时没有问题,但是当我尝试更新文件时,如果我打印到文件末尾带有“\n”,它会在两行之间插入双回车。如果我没有,它会把所有的数据放在一行

我该怎么办

i、 我添加了一个从文件读取和更新文件的函数示例

Employees** Init_Gym_emp(Employees** emp, int* num) {
    FILE* f = fopen("Gym Employees.txt", "r");
    if (f == NULL) {
        printf("Failed opening the file. Exiting!\n");
        exit(1);
    }
    char c = '\0';
    while (fscanf(f, "%c", &c) == 1) {
        if (c == '\n') num[0]++;
    }
    if (num[0] > 0) num[0]++;
    fseek(f, 0, SEEK_SET);
    Employees* tmp = (Employees*)malloc(sizeof(Employees));
    if (tmp == NULL) {
        printf("Memory allocation failed\n");
        exit(1);
    }
    emp = (Employees**)malloc(sizeof(Employees*)*(num[0]));
    if (emp == NULL) {
        printf("Memory allocation failed\n");
        exit(1);
    }
    int i = 0;
    tmp->first_name = (char*)malloc(sizeof(char)* 20);
    tmp->last_name = (char*)malloc(sizeof(char)* 20);
    tmp->user_name = (char*)malloc(sizeof(char)* 20);
    tmp->password = (char*)malloc(sizeof(char)* 20);
    tmp->user_type = (char*)malloc(sizeof(char)* 20);
    while (fscanf(f, "%20[^#]%*c%20[^#]%*c%ld%*c%20[^#]%*c%10[^#]%*c%20[^#]%*2c", tmp->first_name, tmp->last_name, &tmp->id, tmp->user_name, tmp->password, tmp->user_type) == 6) {
        emp[i] = (Employees*)malloc(sizeof(Employees));
        if (emp[i] == NULL) {
            printf("Memory allocation failed\n");
            exit(1);
        }
        emp[i]->first_name = (char*)malloc(sizeof(char)* (strlen(tmp->first_name) + 1));
        emp[i]->last_name = (char*)malloc(sizeof(char)* (strlen(tmp->last_name) + 1));
        emp[i]->user_name = (char*)malloc(sizeof(char)* (strlen(tmp->user_name) + 1));
        emp[i]->password = (char*)malloc(sizeof(char)* (strlen(tmp->password) + 1));
        emp[i]->user_type = (char*)malloc(sizeof(char)* (strlen(tmp->user_type) + 1));
        strcpy(emp[i]->first_name, tmp->first_name);
        strcpy(emp[i]->last_name, tmp->last_name);
        strcpy(emp[i]->user_name, tmp->user_name);
        strcpy(emp[i]->password, tmp->password);
        strcpy(emp[i]->user_type, tmp->user_type);
        emp[i]->id = tmp->id;
        i++;
    }
    free(tmp->first_name);
    free(tmp->last_name);
    free(tmp->user_name);
    free(tmp->password);
    free(tmp->user_type);
    free(tmp);
    fclose(f);
    return emp;
}


void update_Gym_emp(Employees** emp, int* num) {
    remove("Gym Employees.txt");
    FILE* f = fopen("Gym Employees.txt", "w");
    if (f == NULL) {
        printf("Failed opening the file. Exiting!\n");
        exit(1);
    }
    int i;
    for (i = 0; i < num[0]; i++) {
        fprintf(f, "%s#%s#%ld#%s#%s#%s#", emp[i]->first_name, emp[i]->last_name, emp[i]->id, emp[i]->user_name, emp[i]->password, emp[i]->user_type);
    }
    fclose(f);
}
Employees**Init\u Gym\u emp(Employees**emp,int*num){
文件*f=fopen(“Gym Employees.txt”、“r”);
如果(f==NULL){
printf(“打开文件失败。正在退出!\n”);
出口(1);
}
字符c='\0';
而(fscanf(f),%c,&c)==1){
如果(c=='\n')num[0]++;
}
如果(num[0]>0)num[0]++;
fseek(f,0,SEEK_集);
员工*tmp=(员工*)malloc(员工人数);
if(tmp==NULL){
printf(“内存分配失败\n”);
出口(1);
}
emp=(员工**)malloc(员工人数*)*(人数[0]);
如果(emp==NULL){
printf(“内存分配失败\n”);
出口(1);
}
int i=0;
tmp->first_name=(char*)malloc(sizeof(char)*20);
tmp->last_name=(char*)malloc(sizeof(char)*20);
tmp->user_name=(char*)malloc(sizeof(char)*20);
tmp->password=(char*)malloc(sizeof(char)*20);
tmp->user_type=(char*)malloc(sizeof(char)*20);
而(fscanf(f,“%20[^#]%*c%20[^#]%*c%ld%*c%20[^#]%*c%10[^#]%*c%20[^#]%*2c”,tmp->名字,tmp->姓氏,&tmp->id,tmp->用户名,tmp->密码,tmp->用户类型)==6){
emp[i]=(员工*)malloc(员工人数);
if(emp[i]==NULL){
printf(“内存分配失败\n”);
出口(1);
}
emp[i]->first_name=(char*)malloc(sizeof(char)*(strlen(tmp->first_name)+1);
emp[i]->last_name=(char*)malloc(sizeof(char)*(strlen(tmp->last_name)+1);
emp[i]->user_name=(char*)malloc(sizeof(char)*(strlen(tmp->user_name)+1);
emp[i]->password=(char*)malloc(sizeof(char)*(strlen(tmp->password)+1);
emp[i]->user_type=(char*)malloc(sizeof(char)*(strlen(tmp->user_type)+1);
strcpy(emp[i]->名字,tmp->名字);
strcpy(emp[i]>姓氏,tmp->姓氏);
strcpy(emp[i]->用户名,tmp->用户名);
strcpy(emp[i]->密码,tmp->密码);
strcpy(emp[i]->用户类型,tmp->用户类型);
emp[i]->id=tmp->id;
i++;
}
免费(tmp->first_name);
免费(tmp->姓氏);
免费(tmp->用户名);
免费(tmp->密码);
免费(tmp->用户类型);
免费(tmp);
fclose(f);
返回emp;
}
无效更新\u健身房\u环境管理计划(员工**emp,int*num){
删除(“Gym Employees.txt”);
文件*f=fopen(“Gym Employees.txt”,“w”);
如果(f==NULL){
printf(“打开文件失败。正在退出!\n”);
出口(1);
}
int i;
对于(i=0;i名字、emp[i]->姓氏、emp[i]->id、emp[i]->用户名、emp[i]->密码、emp[i]->用户类型);
}
fclose(f);
}

以下是编写代码的一种方法

请注意,第一个函数从文件中读取并创建员工记录的二维列表

请注意,第二个函数从二维员工记录列表写入同一个文件

请注意,调用
fscanf()
的字符串长度比相关的输入缓冲区大小小一倍,因为在扫描字符串时,函数将始终向字符串追加NUL字节

强烈建议按以下方式定义Employee结构,而不是按当前的定义方式:

struct Employee
{
    char first_name[20];
    char last_name[20];
    long id;
    char user_name[20];
    char password[10];
    char user_type[20];
};
现在,拟议的守则

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Employee
{
    char *first_name;
    char *last_name;
    long  id;
    char *user_name;
    char *password;
    char *user_type;
};

typedef struct Employee Employees;

// prototypes
void cleanup( Employees **emp );

Employees** Init_Gym_emp(Employees** emp, int* num)
{
    FILE* f = fopen("Gym Employees.txt", "r");
    if (f == NULL)
    {
        perror("fopen for Gym Employees.txt for input failed");
        exit(1);
    }

    // implied else, fopen successful

    char buffer[1024]; // input work area

    // get count of records in file
    while ( fgets(buffer, sizeof(buffer), f) )
    {
        num[0]++;
    }

    // step back to beginning of file to read/parse each record
    if( fseek(f, 0, SEEK_SET) )
    { // then fseek failed
         perror( "fseek to start of file failed" );
         fclose( f );
         exit( EXIT_FAILURE );
    }

    // implied else, fseek successful

    // allocate array of pointers large enough for all records in input file
    if( NULL == (*emp = malloc((size_t)num[0] * sizeof(Employees*) ) ) )
    {
        perror("malloc for array of pointers to Employee records failed");
        cleanup( emp );
        fclose( f );
        exit(1);
    }

    // clear all pointers to NULL, to make cleanup easier
    memset( *emp, '\0', (size_t)num[0] * sizeof( Employees* ));

    char first_name[20];
    char last_name[20];
    long id;
    char user_name[20];
    char password[10];
    char user_type[20];

    int i = 0;
    while( i < num[0] && fgets( buffer, sizeof(buffer), f ) )
    {
        if( 6 != sscanf(buffer,
                        "%19[^#]# %19[^#]# %ld# %19[^#]# %9[^#]# %19[^#]",
                        first_name,
                        last_name,
                        &id,
                        user_name,
                        password,
                        user_type) )
        { // then sscanf failed
            perror( "sscanf for fields of emp record failed" );
            cleanup( emp );
            fclose( f );
            exit( EXIT_FAILURE );
        }

        // implied else, sscanf successful

        // get room for one employee record
        if( NULL == (emp[i] = malloc(sizeof(Employees)) ) )
        {
            perror("malloc for new employee record failed");
            cleanup( emp );
            fclose( f );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful

        (*emp)[i].first_name = strdup( first_name );
        (*emp)[i].last_name  = strdup( last_name );
        (*emp)[i].user_name  = strdup( user_name );
        (*emp)[i].password   = strdup( password );
        (*emp)[i].user_type  = strdup( user_type );
        (*emp)[i].id         = id;
        i++;
    } // end while


    fclose(f);
    return emp;
} // end function: Init_Gym_emp


void update_Gym_emp(Employees** emp, int* num)
{
    FILE* f = fopen("Gym Employees.txt", "w");
    if (f == NULL)
    {
        perror("fopen for Gym Employees.txt for write failed");
        cleanup( emp );
        exit(1);
    }

    // implied else, fopen successful

    for (int i = 0; i < num[0]; i++)
    {
        fprintf(f, "%s#%s#%ld#%s#%s#%s#",
                (*emp)[i].first_name,
                (*emp)[i].last_name,
                (*emp)[i].id,
                (*emp)[i].user_name,
                (*emp)[i].password,
                (*emp)[i].user_type);
    }
    fclose(f);
} // end function: update_Gym_emp
定义GNU源
#包括
#包括
#包括
结构雇员
{
char*名字;
字符*姓氏;
长id;
字符*用户名;
字符*密码;
字符*用户类型;
};
typedef结构雇员;
//原型
空洞清理(员工**emp);
员工**初始健身计划**环境管理计划(员工**环境管理计划,整数*num)
{
文件*f=fopen(“Gym Employees.txt”、“r”);
如果(f==NULL)
{
perror(“fopen for Gym Employees.txt用于输入失败”);
出口(1);
}
//否则,fopen成功了
字符缓冲区[1024];//输入工作区
//获取文件中记录的计数
while(fgets(buffer,sizeof(buffer),f))
{
num[0]++;
}
//返回到文件的开头以读取/分析每条记录
if(fseek(f,0,SEEK_SET))
{//然后fseek失败了
perror(“fseek to start of file failed”);
fclose(f);
退出(退出失败);
}
//否则,fseek将成功
//为输入文件中的所有记录分配足够大的指针数组
如果(NULL==(*emp=malloc((size_t)num[0]*sizeof(Employees*))
{
perror(“指向员工记录的指针数组的malloc失败”);
清理(emp);
fclose(f);
出口(1);
}
//清除所有指向NULL的指针,使清理更容易
memset(*emp,'\0',(size_t)num[0]*sizeof(Employees*);
char first_name[20];
char last_name[20];
长id;
字符用户名[20];
字符密码[10];
字符用户类型[20];
int i=0;
而(i