0

C++ を学習するために、ファイル パーサー関数のコードに取り組んでいます。

このテキストファイルを読み取ることになっています:

>FirstSeq
AAAAAAAAAAAAAA
BBBBBBBBBBBBBB
>SecondSeq
TTTTTTTTTTTTTT
>ThirdSequence
CCCCCCCCCCCCCC
>FourthSequence
GGGGGGGGGGGGGG

名前 (先頭に '>' がある行) とシーケンスを出力します。ただし、出力から:

AAAAAAAAAAAAAABBBBBBBBBBBBBB
TTTTTTTTTTTTTT
CCCCCCCCCCCCCC
FirstSeq
SecondSeq
ThirdSequence
FourthSequence

G 文字の最後の行が含まれていないことがわかります。コードは以下です。名前が見つかった場合は名前のベクトルに追加され、シーケンスが見つかった場合は一時的な文字列に追加されます (シーケンスが最初のシーケンスのように複数行の場合)。次に、次のシーケンスの名前が見つかると、構築された一時文字列をベクトルに格納し、一時文字列を上書きして最初からやり直します。関数のwhileループにあるためだと思います:行fullSequence.push_back(currentSeq);古い一時文字列をベクトルにプッシュするために以前に新しい名前が検出されたときに呼び出されるこれは、G の最後の行では呼び出されないため、含まれていませんが、名前「FourthSeq」は記録されていますが、 G は一時文字列に読み込まれますが、ベクトルには渡されません。では、これがファイルの最後の行であることを検出できるようにするにはどうすればよいので、一時的な文字列がベクトルにプッシュされるようにする必要がありますか?

ありがとう、ベン。

コード:

#include<fstream>
#include<iostream>
#include<string>
#include<vector>
void fastaRead(string fileName)
{
    ifstream inputFile;
    inputFile.open(fileName);
    if (inputFile.is_open()) {
        vector<string> fullSequence, sequenceNames;
        string currentSeq;
        string line;
        bool newseq = false;
        bool firstseq = true;
        cout << "Reading Sequence" << endl;
        while (getline(inputFile, line))
        {
            if (line[0] == '>') {
                sequenceNames.push_back(line.substr(1,line.size()));
                newseq = true;
            } else {
                if (newseq == true) {
                    if(firstseq == false){
                        fullSequence.push_back(currentSeq);
                    } else {
                        firstseq = false;
                    }
                    currentSeq = line;
                    newseq = false;
                } else {
                    currentSeq.append(line);
                }
            }
        }
        //Report back the sequences and the sequence names...
        for ( vector<string>::iterator i = fullSequence.begin(); i != fullSequence.end(); i++) {
            cout << *i << endl;
        }
        for ( vector<string>::iterator i = sequenceNames.begin(); i != sequenceNames.end(); i++) {
            cout << *i << endl;
        }
        cout << fullSequence.size() << endl;
        cout << sequenceNames.size() << endl;
        inputFile.close();
    } else {
        perror("error whilst reading this file");
    }
    if(inputFile.bad()){
        perror("error whilst reading this file");
    }
}

int main()
{
    cout << "Fasta Sequence Filepath" << endl;
    string input = "boop.txt";
    fastaRead(input);
    return 0;
}
4

1 に答える 1

2

Getline() は、行に EOF が見つかると「失敗」するため、最後に読んだ行はループを通過しません。

私はこの問題を 2 つの方法で解決しました。2 つのフラグを設定するか、ループの後の最後の行を処理するだけです。

2 つのフラグの場合、ループでは両方が true である必要があり、getline() が失敗したときに 1 つを false に設定し、最初のフラグが false の場合はもう 1 つを false に設定します。これにより、EOF の後に 1 つの余分なループが得られます。

幸運を!

于 2013-11-07T16:58:15.107 に答える