【转】C链表写入文件,读出文件操作

来源:互联网 发布:软件安全性测试过程 编辑:程序博客网 时间:2024/06/13 12:47

转载自 wuhuang040924

先附上一份文件读写操作:(今天一天头都晕,快成猪脑子了^_^)


//写函数,
#include<unistd.h>
ssize_t write(int fd,const void *buf,size_t nbytes));
      返回值:成功返回写入文件的字节数,失败返回-1
write函数向filedes文件中写入nbytes字节数据,数据来源为buf.


ssize_t read(int fd,const void *buf,size_t nbytes);
     返回值:成功返回写入的字节数,0则碰到EOF。失败返回-1
read函数从filedes文件中读取nbytes字节数据,存放于buf中。


#include<fcntl.h>
   int open(const char *pathname,int oflag,mode_t mode)
     返回文件句柄
   第一个参数是待打开/创建的文件的路径名;oflag用于指定文件的打开/创建模式,这个参数可由以下常量通过逻辑构成。
      O_RDONLY      只读模式 YcWLinux联盟
      O_WRONLY      只写模式 YcWLinux联盟
      O_RDWR        读写模式YcWLinux联盟
   打开/创建文件时,至少得使用上述三个中的一个,搭配下面:
      O_APPEND       每次写操作都写入文件的末尾 YcWLinux联盟
      O_CREAT        如果指定文件不存在,则创建这个文件 YcWLinux联盟
      O_EXCL         如果要创建的文件已存在,则返回 -1,并且修改 errno 的值YcWLinux联盟
      O_TRUNC        如果文件存在,并且以只写/读写方式打开,则清空文件全部内容 YcWLinux联盟
      O_NOCTTY       如果路径名指向终端设备,不要把这个设备用作控制终端。YcWLinux联盟
      O_NONBLOCK     如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/OYcWLinux联盟
                       设置为非阻塞模式(nonblocking mode)

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#define N 10
typedef struct node
{
char name[20];
struct node *next;
}stud;

//将链表写入文件


stud * create(int n)
{
stud *p,*h,*s;
int i;
h=NULL;   //经常忘记定义这里,导致下面执行Segment fault!!
for(i=0;i<n;i++)
{
    if((s=(stud *)malloc(sizeof(stud)))==NULL)
    {
      printf("malloc space failed!\n");
      exit(0);

     }
   if(h==NULL)
     h=s;
   else
     p->next=s;
   printf("please enter name:");
   scanf("%s",s->name);
   p=s; 
    }
s->next=NULL;
   return h;
}

void print(stud * head)
{
   while(head)
   {
      printf("name:%s\n",head->name);
      head=head->next;

    }

}

//从文件中读出链表
stud * read_userman()
{
   int fd,usersize,rc;
   stud *p1,*p2;
   stud temp;
   static stud head;
   usersize=sizeof(stud);
   fd=open("/tmp/user.txt",O_CREAT|O_RDONLY);
   if(fd<0)
      return;
   rc=read(fd,&temp,usersize);
   p1=&head;
   while(rc>0)
   {
     p1->next=(stud *)malloc(usersize);
     memcpy(p1->next,&temp,usersize); 
      p1=p1->next;
      p1->next=NULL;
      memset(&temp,0,usersize);
      rc=read(fd,&temp,usersize);          
   }
close(fd);
if(p1==&head)
     return NULL;
return head.next;
}

int main()
{
   stud *head;
   head=create(N);
   print(head);
   write_username(head);
    head=read_userman();
    print(head);
    return 0;
}

//当频繁读取链表时,会引起程序错误。下面程序为一删除N个数据,原来做法为删一个写入文件,删一个写入文件,频繁操作,会引起程序进程死亡。所以做法改为 一次删除N个数据,都是在内存中进行,直到删除完全部数据,再写回文件。这样就不会引起进程的死亡了。

int delete_sslclient_userman_memonry()
{
struct sslclient_userman first_userman,*userman,*pre_userman;
FILE *fp;
char usernum[10];
int id;
   userman=read_sslclient_userman_conf();
first_userman.next=userman;
pre_userman=&first_userman;

fp=fopen("/tmp/user.txt","r");
while(1)
{
        if(fgets(usernum,10,fp)==NULL)
        break;
         id=atoi(usernum);
        while((userman->user_num!=id)&&(userman->next!=NULL)){
   pre_userman=userman;
   userman=userman->next;
   } 

if (userman->next==NULL)
   {
   pre_userman->next=NULL;
        write_sslclient_userman_conf(first_userman.next);
        return 1;
   }
else
   {
   pre_userman->next=userman->next;
   }

userman=first_userman.next;
}
write_sslclient_userman_conf(first_userman.next);

return 0;
}