计划以序列的名称读取,将该名称设置为动态数组的变量,并使用 malloc/realloc 处理存储实际序列,以便以后比较所有不同的序列。我可以处理除变量变量名之外的所有内容。
不要用序列头/名称来命名变量,而是创建一个struct 来保存序列头/名称和序列,例如:
typedef struct {
char *header;
char *sequence;
} fasta_t;
然后创建fasta_t指针列表(“指向指针的指针”):
fasta_t **fasta_elements = NULL;
使用malloc() 为N 类型为fasta_t * 的元素分配空间,例如:
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'th 元素的头部,例如:
fprintf(stdout, "%s\n", fasta_elements[i]->header);
(请记住,C 中的索引是从 0 开始的——例如,第 10 个元素的索引为 9。)
完成后,请务必在 fasta_t * 指针、fasta_t * 指针本身以及 fasta_t ** 指向指针的指针中添加 free() 各个指针:
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;
为方便起见,一旦您掌握了处理structs 和内存管理的窍门,您将需要编写用于设置、访问、编辑和分解fasta_t * 元素的包装器函数以及包装器对fasta_t * 元素列表执行相同操作的函数。