プランはシーケンスの名前で読み取られ、その名前を動的配列の変数として設定し、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
ヘッダーとシーケンスにスペースを割り当てます。char *
fasta_t
#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);
(C では、インデックスは 0 から始まることに注意してください。たとえば、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 *
要素。