2013-01-22 58 views
0

我正在用C编写一个程序来读取来自FASTA文件和每个名称的文本(例如:COTV-SPAn232-096)我希望我的程序能够识别'>',然后在\ n之前使用以下文本作为变量的名称。编写一个程序来创建它需要的变量C

硬编码变量的问题在于,该程序需要尽可能动态,因为它可能会读取任意数量的不同数据集。例如我的测试集有看起来像这样15个不同的序列:

COTV-SPAn232-096 MKILNSYNDFIISFINFILFPTIQNVSISKLNILGYILSFIRIISISMDFDILKFSNIIQDYGLIFPDDIKKIQNEKFLVLERGLSGKLYAIHIYDFMARFDNETIFGIAKFLYRNNTKILDVLFINKDLFDKTDILYPKSTITLSSYSDEYIDYTYKTIKLIFLNLFNSFRFSKIDSKLSYLYLPLRKDINNVIL

该计划是在序列名读取,设置名称为变量用于动态数组,并使用malloc/realloc来处理存储实际序列,以便以后比较所有不同的序列。我可以处理除变量名之外的所有内容。

简单地寻找答案,似乎它不能在C中完成,但可以在Python和一些其他语言。我真的希望这不是实际情况,但是如果它是有人有处理这个问题的其他建议吗?是的,这是生物信息学,我可能应该使用python,perl,java或其他语言,但我宁愿继续在C中的这个问题,以进一步精通于C.

在此先感谢任何答案,我可能会收到!

+0

在C中工作以成为精通C的方式是可以理解的。但是考虑到你的领域,你会留在C多久?更多的“现代”语言具有文本/字符串操作功能,比C语言更好用,更容易使用,很难想象你长期留在C中。但是,学习C一段时间是值得的。 – DWright

+0

我推荐学习C,因为Python在I/O操作上很慢。在现代Linux系统中,即使使用“Pythonic”代码,在读取标准输入和写入标准输出时,Python的速度可能比C慢9-10倍。许多生物信息学是关于解析和处理文本文件的,所以如果你打算编写尽可能快的软件,C并不是唯一的出路,但它往往比Python,Perl或其他解释脚本语言。 –

+1

你试过Malloc吗? –

回答

6

这是不可能在C,但从未与动态名称创建变量的理由(事实上,甚至一度您创建用C这样的变量,你将如何使用它们?)

相反,使用一个hash table - 这是一个从键映射到值的数据结构。在你的情况下,你会希望它从字符串(你的序列名称)映射到字符串(你的序列)。

散列表的C库的例子在线比比皆是:StackOverflow question提供了一些例子。

2

坏消息是它不能在C中完成,因为C变量是编译时的概念。变量作为包含数据的内存区域的“标签”一旦编译器完成,大多数变量的名字就会被抛弃。它们可以写入调试器的单独文件,但这对人类来说是一个方便。

好消息是,你不需要一个新变量来命名一个新名称。所有你需要的是包含一个名字的第二个变量。一对变量 - 一个用于name和一个用于value是您所需要的。

2

该计划以序列的名称读取,将该名称设置为动态数组的变量,并使用malloc/realloc处理存储实际序列以便稍后比较所有不同序列。我可以处理除变量名之外的所有内容。

不是使用序列标题/名称命名该变量,而是创建一个struct,其中包含序列标题/名称和序列,例如,:

typedef struct { 
    char *header; 
    char *sequence; 
} fasta_t; 

然后创建的fasta_t指针列表( “指针的指针”):

fasta_t **fasta_elements = NULL; 

使用malloc()fasta_t *类型,例如N元素分配空间

fasta_elements = malloc(N * sizeof(fasta_t *)); 

这是一个好主意,检查,如果你真的有你要的记忆:

if (!fasta_elements) { 
    /* i.e., if fasta_elements is still NULL */ 
    fprintf(stderr, "ERROR: Could not allocate space for FASTA element list!\n"); 
    return EXIT_FAILURE; 
} 

(你应该得到与每一个指针,你malloc()这样的习惯,在我观点。)

现在空间已经分配,​​在N元素(使用realloc()如果我们需要做出的排行榜大,但让我们假设N元素现在)读取。在一个循环中,fasta_t指针内分配为单个fasta_t指针的空间,以及空间的标头和序列char * S:

#define MAX_HEADER_LENGTH 256 
#define MAX_SEQUENCE_LENGTH 4096 

/* ... */ 

size_t idx; 
char current_header[MAX_HEADER_LENGTH] = {0}; 
char current_sequence[MAX_SEQUENCE_LENGTH] = {0}; 

for (idx = 0U; idx < N; idx++) 
{ 
    /* set up space for the fasta_t struct members (the header and sequence pointers) */ 
    fasta_elements[idx] = malloc(sizeof(fasta_t)); 

    /* parse current_header and current_sequence out of FASTA input */ 
    /* ... */ 

    /* validate input -- does current_header start with a '>' character, for instance? */ 
    /* data in bioinformatics is messy -- validate input where you can */ 

    /* set up space for the header and sequence pointers */ 
    /* sizeof(char) is redundant in C, because sizeof(char) is always 1, but I'm putting it here for completeness */ 
    fasta_elements[idx]->header = malloc((strlen(current_header) + 1) * sizeof(char)); 
    fasta_elements[idx]->sequence = malloc((strlen(current_sequence) + 1) * sizeof(char)); 

    /* copy each string to the list pointer, for which we just allocated space */ 
    strncpy(fasta_elements[idx]->header, current_header, strlen(current_header) + 1); 
    strncpy(fasta_elements[idx]->sequence, current_sequence, strlen(current_sequence) + 1); 
} 

要打印出i+1“个元素的首标,例如:

fprintf(stdout, "%s\n", fasta_elements[i]->header); 

(记住索引是基于0用C - 第10元件具有索引9,例如。)

完成后,一定要free()各个指针一个fasta_t *指针,fasta_t *指针本身,然后fasta_t **指针的指针中:

for (idx = 0U; idx < N; idx++) 
{ 
    free(fasta_elements[i]->header), fasta_elements[i]->header = NULL; 
    free(fasta_elements[i]->sequence), fasta_elements[i]->sequence = NULL; 
    free(fasta_elements[i]), fasta_elements[i] = NULL; 
} 
free(fasta_elements), fasta_elements = NULL; 

为方便起见,一旦你处理struct S和内存管理的窍门,你会想要写的包装功能设置,访问,编辑和分解fasta_t *元素,以及对fasta_t *元素列表执行相同操作的包装函数。

相关问题