最近由於項目需要實現修改文件的功能,所以,博主認真查閱了一些資料,但是,很遺憾,並沒有太多的 收獲。
好的,首先我先敘述下功能要求:
其實很簡單,就是Shell中sed命令的C語言實現,實 現定位到所需要的字段的那一行,之後修改成需要的內容。但是由於C語言是面向過程的語言,需要順序執行 的特點,所以,實現中遇到了很多麻煩,在這裡博主將實現的過程描述如下,以便大家參考。
問題描 述:
文本內容:
wireless.1.authmode=1 wireless.1.compression=0 wireless.1.current_ap=ssid12 wireless.1.current_state=1 wireless.1.devname=ath0 wireless.1.enable_slave1_status=disabled wireless.1.enable_slave2_status=disabled wireless.1.enable_slave3_status=disabled
我需要做的就是修改第四行的內容,使之變為:
wireless.1.current_state=0
問題看似簡單,實現過程頗費周折。。。
這裡我給出實 現的代碼,注釋已經加在代碼中:
/* * Author:DLUTBruceZhang * Date: 2013.06.24 */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> int main() { /* *linebuffer:讀取文件中的一行存入的緩沖 *buffer1:一行中第一個字段的存入緩沖 *buffer2:一行中第二個字段的存入緩沖 */ char linebuffer[512] = {0}; char buffer1[512] = {0}; char buffer2[512] = {0}; int line_len = 0; int len = 0; int res; /* * cc.cfg是文件名,r+代表可以讀寫文件 */ FILE *fp = fopen("cc.cfg", "r+"); if(fp == NULL) { printf("open error"); return -1; } while(fgets(linebuffer, 512, fp)) { line_len = strlen(linebuffer); len += line_len; /* * buffer1=wireless.1.current_state * buffer2=1 */ sscanf(linebuffer, "%[^=]=%[^=]", buffer1,buffer2); if(!strcmp("wireless.1.current_state", buffer1)) { /* * 由於已經找到所需要寫的位置,所以需要寫位置的“頭” */ len -= strlen(linebuffer); /* * 實現文件位置的偏移,為寫文件做准備 */ res = fseek(fp, len, SEEK_SET); if(res < 0) { perror("fseek"); return -1; } strcpy(buffer2, "=0"); /*strcat(buffer1, "=");*/ strcat(buffer1, buffer2); printf("%d",strlen(buffer1)); /* * 寫文件,存入所需的內容 */ fprintf(fp, "%s", buffer1); fclose(fp); return; } } return 0; }
保存文件名為:my_sed.c
運行效果如下:
我們再來看文件中的內容已經 變為:
<span style="font-size:18px;"><strong>wireless.1.authmode=1 wireless.1.compression=0 wireless.1.current_ap=ssid12 wireless.1.current_state=0 wireless.1.enable_slave1_status=disabled wireless.1.enable_slave2_status=disabled wireless.1.enable_slave3_status=disabled</strong></span>
實現原理:
這裡實現的效率比較高,因為不是把整個文件的內容裝入緩沖區中,而是一行一行的讀取,知道匹配為止,之 後利用寫文件的特性,直接覆蓋所寫內容即可,由此完成所需功能