0

ファイルがあり、最後の行のみをコンソールに出力したい。

これが私がそれを行う方法についての私の考えです。file.seekg(0, ios::end)自分自身をファイルの最後に置くために使用します。

次に、デクリメント変数int decrement = -1;を作成し、while ループを使用できます。

 while (joke.peek() != '\n')
 {
     decrement--;

 }

最後の行の開始位置を取得します (最後から逆行します)。

これを知ってjoke.seekg(decrement, ios::end);いれば、最終行の先頭に設定する必要があり、以前に宣言したと仮定string input; すると、

 getline(joke, input);
 cout << input << endl;

コンソールに出力します。

完全なコード

 void displayLastLine(ifstream &joke)
 {
    string input;
    int decrement = -1;


    joke.clear();
    joke.seekg(0, ios::end);


    while (joke.peek() != '\n')
    {
        decrement--;

    }
    joke.clear();

    joke.seekg(decrement, ios::end);

    getline(joke, input);
    cout << input << endl;

}

問題は、ファイルに対してこのメ​​ソッドを呼び出しても何も起こらないことです。私がそれをステップスルーすると、デクリメントは 1 を減算し続け、a の場所をはるかに超えてい'\n'ます。テキスト ファイルの例を挙げると、次のようになります。

ジャンク

ごみ

この行をスキップ

これが私たちが探しているラインです!

4

3 に答える 3

1
joke.seekg(0, ios::end);

これにより、ファイルが最後に配置されます。

while (joke.peek() != '\n')

さて、ここで問題 1 です。ファイルの最後にいるときは、peek()常に を返しますEOF

    decrement--;

あなたが書く:

それをステップスルーすると、デクリメントは 1 を減算し続けます。

ループが実行するのはそれだけなので、何が起こると予想していましたか? ループが行う唯一のことは、forから 1 を引くことdecrementです。それが起こることです。

これはよくある問題です。コンピューターは、ユーザーが実行したいことではなく、ユーザーが指示したことだけを実行します。

これは最適ではありませんが、欠けているステップは、 の前に1 文字戻るpeek()必要があることです。seek()次に、peek()現在のカーソル位置の文字を表示します。次に、seek()もう 1 文字戻って、peek()もう一度確認します。

しかし、それだけでは十分ではありません。ほとんどのテキスト ファイルは、改行文字で終わります。つまり、改行はファイルの最後の文字です。したがって、欠落している を追加し直してもseek()、ほとんどの場合、コードは最終的にファイルの最後の文字、つまり最後の改行文字を見つけることになります。

私がお勧めするのは、コードを書くのを少しやめて、代わりに、やりたいことを実行するための論理的なプロセスを考え出し、このプロセスを平易な言葉で説明することです。次に、提案された行動方針についてラバーダックと話し合います。ゴム製のアヒルがあなたの提案が機能することに同意した後でのみ、平易な言葉による記述をコードに変換します。

于 2016-05-18T01:15:25.977 に答える
0

あなたのループは実際には「デクリメント」をデクリメントしているだけで、次の検索には使用していません。

while (joke.peek() != '\n')

{
    joke.seekg(decrement, std::ios::end);
    decrement--;
}
于 2016-05-18T01:54:13.590 に答える