之前立了一个学习C语言的flag,
这一次我要真正学会C语言
,虽然很久没有写相关的推送,但是一直也在默默学习。
昨天看了
Linux的日常·单行数据转fasta后
,因为需求简单,想着也不复杂,于是我就试试了用C语言实现这个小功能。
任务是将下面格式文本
名称1 tab分隔 名称2 tab分隔 名称3 tab分隔 序列 tab分隔 null
转成如下的格式
>名称1|名称2|名称3
序列
我写的代码总共就36行。
#include
#include
#include "klib/kseq.h"
KSTREAM_INIT(gzFile, gzread, 16384)
typedef struct {
char name[256];
char comment1[256];
char comment2[2048];
char seq[2048];
}
Fasta ;
int main(int argc, char const *argv[])
{
gzFile fp;
kstream_t *ks;
kstring_t str = {0,0,0};
if ( argc == 1){
fprintf(stderr, "Usage: %s ", argv[0]);
}
fp = gzopen(argv[1], "r");
ks
= ks_init(fp);
Fasta *fa = (Fasta *)malloc(sizeof(Fasta));
while ( ks_getuntil(ks, '\n', &str, 0) >= 0){
sscanf(str.s, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t", fa->name, fa->comment1, fa->comment2, fa->seq);
printf(">%s %s %s\n%s\n", fa->name, fa->comment1, fa->comment2, fa->seq);
}
ks_destroy
(ks);
gzclose(fp);
free(str.s);
free(fa);
return 0;
}
最开始的三行用于导入头文件,类似于R语言的
library
,Python里的
import
。着重介绍的是
kseq
.
h
, 这是attractivechaos写的klib库中的一个头文件,一个非常高效文本读取库,几乎在所有李恒大神写的工具里都出现了klib库。
代码的主要部分就是调用了kseq.h读取文本,所以请移步到
C语言-使用klib/kseq.h高效读取行
我增加的内容为定义了一个结构体
Fasta
, 将
sscanf
解析的数据存放到对应的位置。
sscanf(str.s, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t", fa->name, fa->comment1, fa->comment2, fa->seq);
输出用的是
printf
函数
printf(">%s %s %s\n%s\n", fa->name, fa->comment1, fa->comment2, fa->seq);
之后通过下面的方法进行编译
gcc -o one2fa one2fa.c -lz
之后就当做普通的命令行一样使用
./one2fa temp
最后说两句:这里用C语言不是最优解,这是练习而已,这类文本转换建议用sed/python/perl/awk,。当然如果数据量非常大,我觉得还是可以考虑下C/C++的、
推荐阅读
C语言实战课-写一个fastq转fasta的程序
C语言实战-让程序能够处理压缩文件