在Linux环境中用C编写文件时出现的问题
我正试图为大学里的一个项目建立一个健身计划。 我们是在Linux环境中用C语言实现的。 我读取文件时没有问题,但是当我尝试更新文件时,如果我打印到文件末尾带有“\n”,它会在两行之间插入双回车。如果我没有,它会把所有的数据放在一行 我该怎么办 i、 我添加了一个从文件读取和更新文件的函数示例在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");
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