我必须阅读一个可以从可选注释开始的文本文件。 在实践中,我必须跳过文件开头的任何不以’@’或’>’开头的行。 在我的测试用例中,文件看起来像:
# Sun Jul 12 22:04:52 2009 /share/apps/corona/bin/filter_fasta.pl --output=/data/results/solid0065/primary.20090712170542775 # Cwd: /state/partition1/home/pipeline # Title: solid0065_20090629_FC1_Tomate_Heinz_4_5_Kb_Tomate_Heinz_4_5_Kb_01 >125_963_316_F3 T1230330231223011323010013
所以我必须跳过前3行(但一般来说我必须跳过n行)。 我必须用2或4个文件[它们在FILE ** inputFiles中]重复这个。 我试过这个循环:
buffer = (char*) malloc (sizeof(char) * 5000); if (buffer == NULL) notEnoughMemory(); for (i = 0; i ')){ fgetpos(inputFiles[i], &position); fgets(buffer, 4999, inputFiles[i]); } fsetpos(inputFiles[i], &position); }
其中cIn是number_of_input_files + 1.尝试调试它时,循环在读取第四行后正确停止。 但是当我使用setpos时,它不会像我期望的那样回到第四行的开头,而是在第三行的中间。 事实上,如果,正好在fsetpos()之后,我在这些操作后打印缓冲区:
fgets(buffer, 4999, inputFiles[i]); fgets(buffer, 4999, inputFiles[i]);
我明白了:
FC1_Tomate_Heinz_4_5_Kb_Tomate_Heinz_4_5_Kb_01 >125_963_316_F3
任何的想法? 提前致谢
您可以跳过处理您不感兴趣的行:
for (i = 0; i < (cIn-1); i++){ while (fgets(buffer, 4999, inputFiles[i])){ if(buffer[0] == '@' || buffer[0] == '>') { puts(buffer); } /* else do nothing*/ } }
然后你只需要替换puts(buffer);
使用您需要处理有效行的代码。 (尽管如此,从您的示例来看,您似乎只想忽略以#
开头的行,?)
而不是fgetpos(); fsetpos();
fgetpos(); fsetpos();
你可能会用
fseek(inputFiles[i], -strlen(buffer), SEEK_CUR);
(恕我直言)Best是将整个文件读入一个大缓冲区(mmap也是一个选项,如果可用),然后查找并修复行结尾和fasta标题。 这也将减少内存碎片。 它大大简化了’解析器’。
编辑:添加源(它不完美,但上次我检查它,它工作;-)可能不完整,我从一个更大的程序剪断它。
struct fastapart { char * name; char * data; unsigned size; struct roedel *friends; }; struct fastafile { size_t totsize; char *tot; unsigned count; struct fastapart *parts; int *alloc; }; struct fastafile * read_complete_fasta(char *name) { int rc,state; struct fastafile * result; size_t pos,len,cnt,idx; struct strbuff *fwd=NULL,*rev = NULL; result = malloc (sizeof *result); if (!result) return NULL; result->tot = read_complete_file(name , &result->totsize); if (!result->tot) goto failfree; result->count = 0; result->parts = NULL; for (pos=cnt=state=0; pos < result->totsize; ) { switch (state) { case 0: /* find first '>' */ if (result->tot[pos] == '>') { pos++; state=2; continue; } pos += strcspn( result->tot+pos, "n" ); case 1: /* not found: sync to newline */ if (result->tot[pos] == 'n') { pos++; state=0; continue; } else pos++; continue;; case 2: /* Got '>'; grab name */ len = strcspn( result->tot+pos, " tn" ); if (cnt >= result->count) { size_t siz; siz = result->count ? 2* result->count: 16; result->parts = realloc( result->parts , siz * sizeof *result->parts); for ( ; result->count < siz;result->count ++) { result->parts[cnt].name = NULL; result->parts[cnt].data = NULL; result->parts[cnt].friends = NULL; result->parts[cnt].size = 0; } } result->parts[cnt].name = result->tot+pos; result->parts[cnt].name[len] = 0; pos += 1+len; len = strspn( result->tot+pos, " tn" ); pos += len; state++; continue; case 3: /* grab data; for the moment, throw away reversed data */ if (result->tot[pos] == '>') { if (fwd) { memcpy(result->parts[cnt].data, fwd->data, fwd->used ); result->parts[cnt].size = fwd->used; result->parts[cnt].data [ fwd->used ] = 0; fwd->used = 0; } if (rev) { /* memcpy(result->parts[cnt].data+result->parts[cnt].size, rev->data, rev->used ); */ rev->used = 0; } if (result->parts[cnt].data) cnt++; pos++; state=2; continue; } len = strcspn( result->tot+pos, "tn" ); if (!len) { /* empty line; what to do? skip it! */ fprintf(stderr, "Emptyn" ); pos++; state=1; continue; } if (!result->parts[cnt].data) {result->parts[cnt].data = result->tot+pos; } fwd = strbuff_add(fwd, result->tot+pos, len); pos += len; if (result->tot[pos] == 't' ) { pos += strspn(result->tot+pos, " t" ); len = strcspn( result->tot+pos, "n" ); rev = strbuff_add(rev, result->tot+pos, len); pos += len; } pos += strspn(result->tot+pos, " trn" ); }} if (state == 3) { if (fwd) { memcpy(result->parts[cnt].data, fwd->data, fwd->used ); result->parts[cnt].size = fwd->used; result->parts[cnt].data [ fwd->used ] = 0; fwd->used = 0; } if (rev) { /* memcpy(result->parts[cnt].data+result->parts[cnt].size, rev->data, rev->used ); */ rev->used = 0; } if (result->parts[cnt].data) cnt++; } /* final realloc */ result->parts = realloc( result->parts, cnt * sizeof *result->parts); result->count = cnt; free (fwd); free (rev); result->alloc = malloc( result->count * sizeof result->alloc[0] ); if (result->alloc) { for (cnt = 0; cnt < result->count; cnt++ ) result->alloc[cnt] = cnt; } return result; failfree: free (fwd); free (rev); free (result); return NULL; } char * read_complete_file(char *name, size_t *sizep) { int fd, rc; size_t size, len; char *result; struct stat st; fd = open(name, O_RDONLY); if (fd == -1) goto fail; rc = fstat(fd, &st); if (rc == -1) goto closefail; result = malloc (1+st.st_size ); if (!result ) goto closefail; result[st.st_size] = 0; for (size = 0; size < st.st_size;) { rc = read(fd, result, st.st_size - size); if (rc < 0) goto freeclosefail; size += rc; } fprintf(stderr, "Read %lu bytes FROM %sn" , (unsigned long) size, name); close(fd); *sizep = size; return result; freeclosefail: free(result); closefail: close(fd); fail: *sizep=0; return NULL; }
以上就是c/c++开发分享C – 尝试返回文件中的上一行相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522391.html