1

次のコードを実行すると、実際の行数よりも少ない行数が読み取られます (入力ファイルがメイン自体である場合、またはそれ以外の場合)。これはなぜですか。また、その事実を変更するにはどうすればよいですか (1 を追加する以外に)?

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    // open text file for input
    string file_name;

    cout << "please enter file name: ";
    cin  >> file_name;

    // associate the input file stream with a text file
    ifstream infile(file_name.c_str());

    // error checking for a valid filename
    if ( !infile ) {
        cerr << "Unable to open file "
             << file_name << " -- quitting!\n";
        return( -1 );
        }
        else cout << "\n";

    // some data structures to perform the function
    vector<string> lines_of_text;
    string textline;

    // read in text file, line by line
    while (getline( infile, textline, '\n' ))   {
        // add the new element to the vector
        lines_of_text.push_back( textline );

        // print the 'back' vector element - see the STL documentation
        cout << "line read: " << lines_of_text.back() << "\n";
    }
cout<<lines_of_text.size();
    return 0;
}
4

4 に答える 4

2

あなたが持っているコードは健全です。役立つかもしれない小さなテストケースを次に示します。

void read_lines(std::istream& input) {
  using namespace std;
  vector<string> lines;
  for (string line; getline(input, line);) {
    lines.push_back(line);
    cout << "read: " << lines.back() << '\n';
  }
  cout << "size: " << lines.size() << '\n';
}

int main() {
  {
    std::istringstream ss ("abc\n\n");
    read_lines(ss);
  }
  std::cout << "---\n";
  {
    std::istringstream ss ("abc\n123\n");
    read_lines(ss);
  }
  std::cout << "---\n";
  {
    std::istringstream ss ("abc\n123");  // last line missing newline
    read_lines(ss);
  }
  return 0;
}

出力:

read: abc
read: 
size: 2
---
read: abc
read: 123
size: 2
---
read: abc
read: 123
size: 2
于 2010-04-22T22:08:10.597 に答える
2

問題の原因を突き止めたと思います。Code::Blocks では、完全に空のファイルは、IDE の下部にあるステータス バーのギズモに 1 行 (現在の行) があることを報告します。これは、実際にテキスト行を入力すると、1 行目になることを意味します。つまり、Code::Blocks は通常、ファイル内の実際の行数を過大に報告します。ファイルに関する情報を見つけるために、CB やその他の IDE に依存するべきではありません。それは目的ではありません。

于 2010-04-22T22:11:16.913 に答える
0

ファイルの最後の行が単に '\n' である場合、それをベクトルにプッシュしません。そこに置きたい場合は、ループを次のように変更します。

while (getline( infile, textline, '\n' ).gcount() > 0) 
{
    if (infile.fail()) break; //An error occurred, break or do something else

    // add the new element to the vector
    lines_of_text.push_back( textline );

    // print the 'back' vector element - see the STL documentation
    cout << "line read: " << lines_of_text.back() << "\n";
}

メンバーを使用gcount()して、最後の読み取りで読み取られた文字数を確認します。これは、区切り文字のみを読み取った場合に 1 を返します。

于 2010-04-22T21:31:07.620 に答える
-1

わかりましたので、ここに説明がありますので、ご理解いただければ幸いです。話しているファイルが改行で終わらない場合、コードは正常に機能するはずです。しかし、そうなったらどうしますか?次のように見えるとしましょう。

"line 1"
"line 2"
""

または一連の文字として:

line 1\nline 2\n

このファイルには 3 行あります。最後の行は空ですが、そこにあります。getline を 2 回呼び出した後、ファイルからすべての文字を読み取りました。getline への 3 回目の呼び出しでは、oops, end of file, 残念ながらこれ以上文字がありませんと表示されるため、テキストは 2 行しか表示されません。

于 2010-04-22T22:04:40.693 に答える