賀卡制作優(yōu)化資訊
在之前的學(xué)習(xí)中,忘文件中寫的內(nèi)容都是字符串或字符,本節(jié)學(xué)習(xí)如何寫入其他各種類型的數(shù)據(jù)。
回看write和read函數(shù)的形式:
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
其中,第二個(gè)參數(shù)都是一個(gè)無類型的指針,只不過之前一直將這里定義為一個(gè)字符串,其實(shí),這個(gè)指針可以指向各種形式數(shù)據(jù)的地址。?
寫入一個(gè)整數(shù)
demo7.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{int fd; // file descriptionint data = 100;int data2 = 0;fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, &data, sizeof(int));lseek(fd,0,SEEK_SET);read(fd, &data2, sizeof(int));printf("context:%d\n",data2);close(fd); //close after writing return 0;
}
運(yùn)行代碼:
注意,如果此時(shí)打開file1:(此時(shí)需要使用vi打開)
發(fā)現(xiàn)是亂碼,但是這并不影響程序運(yùn)行時(shí)的讀取和寫入。
寫入一個(gè)結(jié)構(gòu)體
demo7.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>struct Test
{int i;char c;
};int main()
{int fd; // file descriptionstruct Test data = {30,'k'};struct Test data2;fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, &data, sizeof(struct Test));lseek(fd,0,SEEK_SET);read(fd, &data2, sizeof(struct Test));printf("data.i:%d,data.c=%c\n",data2.i,data2.c);close(fd); //close after writing return 0;
}
運(yùn)行代碼:
?
?
?寫入一個(gè)結(jié)構(gòu)體數(shù)組
demo7.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>struct Test
{int i;char c;
};int main()
{int fd; // file descriptionstruct Test data[2] = {{30,'k'},{100,'p'}};struct Test data2[2];fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, &data, sizeof(struct Test)*2);lseek(fd,0,SEEK_SET);read(fd, &data2, sizeof(struct Test)*2);printf("data[0].i:%d,data[0].c=%c\n",data2[0].i,data2[0].c);printf("data[1].i:%d,data[1].c=%c\n",data2[1].i,data2[1].c);close(fd); //close after writing return 0;
}
?運(yùn)行代碼:
寫入一個(gè)鏈表?
demo7.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>struct Test
{int data;struct Test *next;
};int main()
{int fd; // file descriptionstruct Test head = {20,NULL};struct Test node1 = {30,NULL};struct Test node2 = {40,NULL};head.next = &node1;node1.next = &node2;fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, &head, sizeof(struct Test));write(fd, &node1, sizeof(struct Test));write(fd, &node2, sizeof(struct Test));lseek(fd,0,SEEK_SET);struct Test node_read_1 = {0,NULL};struct Test node_read_2 = {0,NULL};struct Test node_read_3 = {0,NULL};read(fd, &node_read_1, sizeof(struct Test)); read(fd, &node_read_2, sizeof(struct Test));read(fd, &node_read_3, sizeof(struct Test));printf("no.1=%d\n",node_read_1.data);printf("no.2=%d\n",node_read_2.data);printf("no.3=%d\n",node_read_3.data);close(fd);return 0;
}
運(yùn)行代碼:
?
但是以上的代碼有點(diǎn)笨,且容錯(cuò)性太低,首先讀取和寫入應(yīng)該封裝成函數(shù),并且我認(rèn)為通常在讀取鏈表的時(shí)候,不一定知道鏈表有多少元素,所以應(yīng)該一邊用尾插法動(dòng)態(tài)創(chuàng)建鏈表一邊讀取。
改進(jìn)代碼demo8.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>struct Test
{int data;struct Test *next;
};struct Test *insertBehind(struct Test *head, struct Test *new)
{struct Test *p = head;if(p == NULL){head = new;return head;}while(p->next != NULL){p = p->next;} //將p先移動(dòng)到鏈表的尾部p->next = new;return head;
}void writeLink2File(int fd,struct Test *p){while(p != NULL){write(fd, p, sizeof(struct Test));p = p->next;}
}void readLinkFromFile(int fd,struct Test *head){struct Test *new;int size = lseek(fd,0,SEEK_END); //先計(jì)算文件大小lseek(fd,0,SEEK_SET); //然后不要忘記把光標(biāo)移到文件頭while(1){new = (struct Test *)malloc(sizeof(struct Test));read(fd, new, sizeof(struct Test));printf("link data:%d\n",new->data);if(lseek(fd,0,SEEK_CUR) == size){ //每次讀取一個(gè)數(shù)據(jù)之后,動(dòng)態(tài)創(chuàng)建下一個(gè)鏈表節(jié)點(diǎn)之前,都要判斷“當(dāng)前光標(biāo)是否已經(jīng)在文件尾”,如果是,說明讀取已經(jīng)完成printf("read finish\n");break;}head = insertBehind(head,new);}}int main()
{int fd; // file descriptionstruct Test head = {20,NULL};struct Test node1 = {30,NULL};struct Test node2 = {40,NULL};head.next = &node1;node1.next = &node2;fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);writeLink2File(fd,&head);struct Test *head_recv = NULL; //準(zhǔn)備創(chuàng)建一個(gè)新的鏈表用于接收readLinkFromFile(fd,head_recv);close(fd);return 0;
}