0

FASTA ファイルからテキストを読み取るプログラムを C で作成しています。すべての名前 (例: >COTV-SPAn232-096) について、プログラムに「>」を認識させ、次のテキストを \n の前に使用して、変数の名前として使用されます。

変数をハードコーディングする際の問題は、このプログラムが任意の数の異なるデータセットを読み取る可能性があるため、可能な限り動的である必要があることです。たとえば、私のテスト セットには、次のような 15 の異なるシーケンスがあります。

COTV-SPAn232-096 MKILNSYNDFIISFINFILFPTIQNVSISKLNILGYILSFIRIISISMDFDILKFSNIIQDYGLIFPDDIKKIQNEKFLVLERGLSGKLYAIHIYDFMARFDNETIFGIAKFLYRNNTKILDVLFINKDLFDKTDILYPKSTITLSSYSDEYIDYTYKTIKLIFLNLFNSFRFSKIDSKLSYLYLPLRKDINNVIL

プランはシーケンスの名前で読み取られ、その名前を動的配列の変数として設定し、malloc/realloc を使用して実際のシーケンスの格納を処理し、後ですべての異なるシーケンスを比較します。変数変数名以外はすべて扱えます。

これに対する答えを簡単に探してみると、Pythonや他の言語ではできますが、Cではできないようです。それが実際のケースではないことを本当に望んでいますが、この問題を処理するための別の提案はありますか? はい、これはバイオインフォマティクスであり、おそらく python、perl、java、またはその他の言語を使用する必要がありますが、C でこの問題を続行して、C にさらに精通したいと考えています。

回答をお待ちしております。よろしくお願いします。

4

3 に答える 3

6

これは C では不可能ですが、動的な名前で変数を作成する理由はありません (実際、C でそのような変数を作成したとしても、それらをどのように使用しますか?)

代わりに、ハッシュ テーブルを使用します。これは、キーから値にマップするデータ構造です。あなたの場合、文字列 (シーケンス名) から文字列 (シーケンス) にマップする必要があります。

ハッシュ テーブル用の C ライブラリの例はオンラインにたくさんあります

于 2013-01-22T01:24:34.143 に答える
2

悪いニュースは、C 変数はコンパイル時の概念であるため、C では実行できないことです。変数は、データを含むメモリ領域の「ラベル」として機能します。コンパイラが完了すると、ほとんどの変数の名前は破棄されます。それらはデバッガー用に別のファイルに書き込まれる場合がありますが、それは人間にとって便利です。

幸いなことに、新しい変数に新しい名前を付ける必要はありません。必要なのは、名前を含む 2 番目の変数だけです。変数のペア - 1 つと 1 つnamevalue必要です。

于 2013-01-22T01:26:22.233 に答える
2

プランはシーケンスの名前で読み取られ、その名前を動的配列の変数として設定し、malloc/realloc を使用して実際のシーケンスの格納を処理し、後ですべての異なるシーケンスを比較します。変数変数名以外はすべて扱えます。

変数にシーケンス ヘッダー/名前を付ける代わりに、structシーケンス ヘッダー/名前とシーケンスを保持する を作成します。例:

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

次に、fasta_tポインターのリスト (「ポインターへのポインター」) を作成します。

fasta_t **fasta_elements = NULL;

タイプの要素にmalloc()スペースを割り当てるために使用します。:Nfasta_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;

便宜上、structs とメモリ管理の扱いに慣れたら、要素の設定、アクセス、編集、分解を行うラッパー関数と、fasta_t *要素のリストに対して同じことを行うラッパー関数を記述します。fasta_t *要素。

于 2013-01-22T01:29:48.977 に答える