文件逆顺输出到新文件(三种方案)
生活随笔
收集整理的這篇文章主要介紹了
文件逆顺输出到新文件(三种方案)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
方法一:利用遞歸
/*功能:文件以行為單位,逆順輸出到新文件示例:file1.txt為:123456要求逆順后輸出到文件file2.txt,結(jié)果為:563412*/#include <stdio.h> #include <string.h>// 遞歸讀取文件 void doread(FILE *fp1, FILE *fp2, int next) {char buf[1024] = {0};if(next && fgets(buf, 1024, fp1) != NULL)doread(fp1, fp2, next);else if(next)next = 0; // 讀到文件尾fwrite(buf, strlen(buf), 1, fp2); // 寫入新文件 }int run(char *infile, char *outfile) {FILE *fp1 = NULL, *fp2 = NULL;if( NULL == (fp1 = fopen(infile, "r")) || NULL == (fp2 = fopen(outfile, "w")) )return 0;doread(fp1, fp2, 1);fclose(fp1);fclose(fp2);return 1; }int main() {char infile[] = "file1.txt";char outfile[] = "file2.txt";run(infile, outfile);return 0; }
====================================================================================
方法二:利用鏈表(頭插入法)
考慮到逆序的思想就是后進(jìn)先出,這與棧的功能非常相似,于是產(chǎn)生了下面這種解法:
/*功能:演示了將文件中的內(nèi)容以行為單位,逆順輸出到另一文件思路:考慮到后進(jìn)先出,采用類似于棧的思想 */ #include <stdio.h> #include <string.h> #include <stdlib.h>typedef struct _tagNode {char *line;struct _tagNode *next; }Node;Node* insert(Node *head, char *line) // 頭插法建立鏈表 {Node *p = malloc(sizeof(Node));p->line = malloc(strlen(line)+1);strcpy(p->line, line);p->next = head;head = p;return head; }void display(Node *head) {int i = 0;while(head){printf("L%d: [%s]\n", ++i, head->line);head = head->next;} }// 將文件中的內(nèi)容以行為單位逆順輸出到另一文件 void reverse(FILE *fp1, FILE *fp2) {int i = 0;char line[1024] = {0};Node *head = NULL, *t = NULL;// 讀文件,建立鏈表while(fgets(line, 1024, fp1) != NULL) // fgets默認(rèn)會(huì)將換行符讀入到line中{if(line[strlen(line)-1] == '\n') // 最后一個(gè)是換行符line[strlen(line)-1] = 0;//printf("L%d: [%s]\n", ++i, line);head = insert(head, line); // 頭插法建立鏈表} // display(head);// 順序讀取鏈表,輸出內(nèi)容到文件,并釋放結(jié)點(diǎn)while(head){fprintf(fp2, "%s\n", head->line); // 將內(nèi)容寫入輸出文件t = head; // t指向要?jiǎng)h除的結(jié)點(diǎn)head = head->next; // head后移free(t->line);free(t);} }int main() {FILE *fp1, *fp2;char fin[] = "a.txt", fout[] = "a_out.txt";fp1 = fopen(fin, "r");fp2 = fopen(fout, "w");if(fp1 == NULL || fp2 == NULL){printf("Open file error\n");return 1;}reverse(fp1, fp2); // 將文件中的內(nèi)容以行為單位逆順輸出到另一文件fclose(fp1);fclose(fp2);return 0; }==================================================================================================
方法三:利用內(nèi)存映射
/*功能:利用內(nèi)存映射將文件中的內(nèi)容以行為單位,逆順輸出到另一文件說(shuō)明:如果最后一行無(wú)換行符,在輸出文件中會(huì)被添加上去(否則會(huì)與第二行連在一起) */ #include <sys/mman.h> /* for mmap and munmap */ #include <sys/types.h> /* for open */ #include <sys/stat.h> /* for open */ #include <fcntl.h> /* for open */ #include <unistd.h> /* for lseek and write */ #include <stdio.h>// 以行為單位,將mapped_mem中的內(nèi)容逆順輸出到文件fout void reverse(char *mapped_mem, int flen, int fout) {char *p, *t;t = p = mapped_mem + flen - 1; // p指向內(nèi)容的最后一個(gè)字節(jié)if(*p != '\n' && *p != '\0') // 最后一個(gè)字節(jié)不是換行符或0t = p + 1;p--;while(p >= mapped_mem) // 從末尾向前掃描{while(p >= mapped_mem && *p != '\n')p--;write(fout, p+1, t-p-1); // 將[p+1, t)的內(nèi)容輸出到文件foutwrite(fout, "\n", 1); // 輸出換行符t = p--;}if(t == mapped_mem) // 第一行是空行{write(fout, "\n", 1);} }int main(int argc, char **argv) {int fd, fd_out;char *mapped_mem = NULL;int flength = 1024;void * start_addr = 0;if(argc < 3){printf("Usage: %s <file_in> <file_out>\n", argv[0]);return 1;}fd = open(argv[1], O_RDONLY, S_IRUSR | S_IWUSR);fd_out = open(argv[2], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);if(fd == -1 || fd_out == -1){perror("open");return 1;}flength = lseek(fd, 0, SEEK_END); // 求得文件長(zhǎng)度mapped_mem = mmap(start_addr, flength, PROT_READ, //允許讀MAP_PRIVATE, //不允許其它進(jìn)程訪問(wèn)此內(nèi)存區(qū)域fd, 0);if(mapped_mem == MAP_FAILED){perror("mmap");return 1;}reverse(mapped_mem, flength, fd_out); // 逆順輸出文件內(nèi)容到fd_outclose(fd);close(fd_out);munmap(mapped_mem, flength);return 0; }總結(jié)
以上是生活随笔為你收集整理的文件逆顺输出到新文件(三种方案)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《Access 2007开发指南(修订版
- 下一篇: 《NoSQL权威指南》导读