看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Linux 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) zlib.h 用來處理壓縮的檔案 (問題是卡在開檔完的部分,可以只視為是 要處理在陣列裡面的字串) 問題(Question): 有兩個檔案會讀進 char *indexBuffer, *dataBuffer index 裡面是存每一筆資料的長短 data 裡面是實際的資料 例如在index裡面 1 50 2 30 3 40 表示第一筆資料在data裡面的前50個bytes 第二筆是接下來的30個 第三筆是在接下去的40個 我現在用 char *tmp=(char *)malloc(data_Size); strncpy (tmp, dataBuffer, data_Size); 可以抓到第一筆的資料 但是我不知道要怎麼做可以讓我在下一個迴圈的時候 可以從50往後面抓30個bytes 好像沒有函式可以直接指定要從哪裡抓到哪裡 我本來的想法是 取完前50個之後,把前50個的資料從buffer裡面移除 那我就可以繼續往下面抓了 不過我參考網路上的CODE好像有問題 所以想請教一下有什麼辦法可以讓我指定要copy的範圍 或是把前面不要的部分從buffer裡面刪除 餵入的資料(Input): http://cis.poly.edu/cs912/data/nz2.tar 程式碼(Code):(請善用置底文網頁, 記得排版) #include <zlib.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define INDEX_CHUNK 409600 //50KB #define DATA_CHUNK 20971520 //2.5MB char *memAlloc(gzFile *, int); void openfile(char *str_index, char *str_data); //char *str_replace (char *source, char *find, char *rep); int main (int argc, char * argv[]) { FILE *cList; char dataName[20]; char index[] = "_index"; char data[] = "_data"; char tmp1[30],tmp2[30]; cList=fopen("nz2_merged/indexfile_list.txt","r"); int counter = 0; char ch; while(fscanf(cList,"%s",dataName) != EOF) { strcpy(tmp1, dataName); strcpy(tmp2, dataName); strcat(tmp1, index); strcat(tmp2, data); //printf("%s %s %s\n",dataName, tmp1, tmp2); if(counter == 0) openfile(tmp1, tmp2); counter++; } printf("This is a %d in main\n", counter); fclose(cList); } /****************************************** *Read a gz file into a buffer *@param fileName the filename to be read *@param size the initial size of the buffer *@return the buffer ******************************************/ char *memAlloc(gzFile *fileName, int size) { char *buffer=(char *)malloc(size); int oldSize=size; int count=0; //The number of bytes that already read while (!gzeof(fileName)) { count+=gzread(fileName,buffer+count,oldSize); //printf("%d %d\n" , count, size); if (count==size) // Reallocate when buffer is full { oldSize=size; size*=2; buffer=(char *)realloc(buffer,size); } } return buffer; } void openfile(char *str_index, char *str_data) { gzFile *cData,*cIndex; char *indexBuffer, *dataBuffer; char *space = "\n"; char url[1000], ip[16], status[3]; int unknown, start_Pos, data_Size, port; cIndex=gzopen(str_index,"r"); indexBuffer=memAlloc(cIndex, INDEX_CHUNK); cData=gzopen(str_data,"r"); dataBuffer=memAlloc(cData, DATA_CHUNK); /* Split string & Start to build the index */ /**********************************************************/ int count = 0; char * pch; char * pos; pch = strtok(indexBuffer, space); while (pch != NULL) { sscanf(pch,"%s %d %d %d %s %d %s", url, &unknown, &start_Pos, &data_Size, ip ,&port, status); //printf("%s \n" , url); //printf("%d \n" , unknown); //printf("%d \n" , start_Pos); //printf("%d \n" , data_Size); //printf("%s \n" , ip); //printf("%d \n" , port); //printf("%s \n" , status); pch = strtok (NULL, space); if(count == 0) { char *tmp=(char *)malloc(data_Size); strncpy (tmp, dataBuffer, data_Size); //if(strncmp (tmp, dataBuffer, data_Size) == 0) //printf("YES \n"); //dataBuffer = str_replace(dataBuffer, tmp, ""); printf("%s \n" , tmp); } /*else { char *tmp=(char *)malloc(data_Size); strncpy (tmp, dataBuffer, data_Size); dataBuffer = str_replace(dataBuffer, tmp, ""); }*/ count++; } /**********************************************************/ //FILE *fp; //fp = fopen("data1.txt","w"); //fprintf(fp,"%s", dataBuffer); printf("This is a %d in openfile\n", count); gzclose(str_index); gzclose(str_data); fclose(fp); } /* char *str_replace (char *source, char *find, char *rep){ // 搜尋文字的長度 int find_L=strlen(find); // 替換文字的長度 int rep_L=strlen(rep); // 結果文字的長度 int length=strlen(source)+1; // 定位偏移量 int gap=0; // 建立結果文字,並複製文字 char *result = (char*)malloc(sizeof(char) * length); strcpy(result, source); // 尚未被取代的字串 char *former=source; // 搜尋文字出現的起始位址指標 char *location= strstr(former, find); // 漸進搜尋欲替換的文字 while(location!=NULL){ // 增加定位偏移量 gap+=(location - former); // 將結束符號定在搜尋到的位址上 result[gap]='\0'; // 計算新的長度 length+=(rep_L-find_L); // 變更記憶體空間 result = (char*)realloc(result, length * sizeof(char)); // 替換的文字串接在結果後面 strcat(result, rep); // 更新定位偏移量 gap+=rep_L; // 更新尚未被取代的字串的位址 former=location+find_L; // 將尚未被取代的文字串接在結果後面 strcat(result, former); // 搜尋文字出現的起始位址指標 location= strstr(former, find); } return result; } */ 補充說明(Supplement): 現在我卡在不知道怎麼樣才可以只copy我想要的範圍 是可以指定我要的範圍 或是把用過的地方從buffer裡面刪除,我直接在往後面抓我要的長度 char *str_replace 是我參考網路上的資料,不過似乎有問題,程式會卡死的樣子 我的vmware就這樣怪怪了好幾次 麻煩大家給我一點意見,謝謝 -- 我不是宅 我只是比較居家 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 108.6.64.30 ※ 編輯: rock1985 來自: 108.6.64.30 (03/15 09:01)
james732:strncpy (tmp, dataBuffer + 50, 30); 03/15 09:34
james732:這樣寫就是從dataBuffer的第50個開始複製30個到tmp去 03/15 09:35
rock1985:太感謝你了,原來這樣就可以了 謝謝你 03/15 09:49
stupid0319:用strncpy???不會漏掉資料嗎 03/15 10:32
stupid0319:看起來用memcpy比較保險 03/15 10:35
bdvstg:推用memcpy,strncpy遇到資料為零時會斷 03/15 11:14
james732:不過如果他是純文字資料的話就沒關係 XDD 03/15 12:13
albertviking:我把程式碼複製下來給devc++後會出現 03/15 13:46
albertviking: E:\Dev-Cpp\Makefile.win [Build Error][專案2.exe] 03/15 13:46
albertviking:Error 1 是為甚麼阿>"< 03/15 13:46
rock1985:我也不知道耶 沒碰到過 我是用linux開發 03/15 13:57
firejox:看能不能用gzseek()來跳躍讀檔指標 03/15 18:30
firejox:zlib裡好像有類似fseek的東西 03/15 19:06
firejox:話說 8樓 你的dev-c++有zlib嗎? 03/15 19:22
firejox:好吧我看錯了... 03/15 19:56
firejox:可以用邊讀邊做來處理 03/15 19:57