1

入力用に新しいファイルを開き、input >> listSize;whileループの外側で呼び出してから呼び出しを続けるとinput >> anothervariable、ファイルは自動的に進行しますか、それとも最初の行を再度読み取りますか?

例:

input >> listSize;
BaseStudent* studentlist = new BaseStudent[listSize.atoi()];
while (!input.eof())
{
         input >> anothervariable; // I want this to start on the second line, not the first

}

入力ファイルは次のようになり、パターンにコーディングできます(余分な空白行は無視してください)。

12

Bunny, Bugs

Math 90 86 80 95 100 99 96 93

Schmuckatelli, Joe

History 88 75 90

Dipwart, Marvin

English 95 76 72 88

Crack Corn, Jimmy

Math 44 58 23 76 50 59 77 68

Kirk, James T. 

English 40 100 68 88

Lewinsky, Monica

History 60 72 78

Nixon, Richard

English 35 99 70 70

Lincoln, Abraham

History 59 71 75

Clinton, William

Math 43 55 25 76 50 58 65

Duck, Donald

English 34 100 65 65

Duck, Daffy

History 55 70 70

Bush, George

Math 44 54 29 75 50 55 60
4

3 に答える 3

3

ストリームから読み取る場合、データが使用されます。
次回は最後のポイントから「up-to」を読みます

ただし、ストリーム演算子>>は空白の続行をスキップしますが、オブジェクトの後の空白は読み取りません(新しい行が簡単に表示されないため、入力が行指向の場合は問題になる可能性があります)。

これを回避する最善の方法は、一度に明示的に行を読み取り、その行を解析することです。

std::string    line;
std::getline(input, line);   // Read a line

// Now look what is in the line.
std::stringstream  linestream(line);
linestream >> dataItem1 >> dataItem2 >> dataItem3; /// etc.

また注意してください:

 // This is not good. If there are any errors in your file it will loop forever.
 while (!input.eof())

以下を使用して入力をループするのは通常のことです。

 while(input >> data)
 {
      // If you get in here then the read worked.
 }
 // You will fall out of the loop when
 //   1) EOF
 //   2) There is an error.

したがって、両方の手法を組み合わせると、次のようになります。

 std::string line1;  // Name,
 std::string line2;  // Scores
 std::string empty;  // Empty line in data file.

 while(std::getline(input, line1) && std::getline(line, empty) && std::getline(input, line2))
 { 
       //  line1 => Bunny, Bugs
       //  empty => 
       //  line2 => Math 90 86 80 95 100 99 96 93

       // Enter the loop only if we get a name and a score line
      std::getline(line, empty); // Optionally read a trailing line (there may not be a last one);

      // dataStream   => Math 90 86 80 95 100 99 96 93
      std::stringstream dataStream(line2);
      std::string   subject;
      int score;

      dataStream >> subject;   // subject => Math
      while(dataStream >> score)
      {
          // We read another score from the data line;

          // score is 90 first time 86 second time etc.
      }
 }
于 2012-07-06T02:14:38.587 に答える
2

あなたの質問に対する答えは「はい」であるとすでに指摘している人もいるので、その部分については心配しません。

残りは少し違う書き方をすると思います。あなたのファイルは明らかに構造化されたデータを表しており、私はその事実を合理的に直接反映するコードを書きます。まず、ファイル内のデータを反映する構造を定義します。

struct test_scores {   // maybe not tests. Change if appropriate
    std::string student;
    std::string course;
    std::vector<int>
};

次に、ファイルからこれらの項目の1つを読み取る関数を記述します。

std::istream &operator>>(std::istream &is, test_scores &ts) { 
    // for the moment assuming there are no blank lines in the file.
    std::getline(is, ts.student);
    std::string temp;
    std::istringstream buffer(temp);
    buffer >> ts.course;
    int score;
    while (buffer>>score)
        ts.scores.push_back(score);
    return is;
}

ただし、C ++では、データの前にカウントを付けるよりも、データの量に関係なく読み取る方が非常に簡単です。カウントが存在する場合、最も簡単な方法は、おそらくそれを読んで無視することです。

std::string ignore;
std::getline(infile, ignore);

そうすれば、実際のデータを非常に簡単に読み取ることができます。

std::vector<test_scores> student_scores;
test_scores tmp;

while (infile >> tmp)
    student_scores.push_back(tmp);

...または、C ++の便利なダンディを使用istream_iteratorして、コードをさらに単純化することができます。

std::vector<test_scores> student_scores((std::istream_iterator<test_scores>(infile)),
                                         std::istream_iterator<test_scores>());

それだけです-それはベクトルを定義し、入力ファイルからそれを初期化します、すべて1つの(かなり)簡単な操作で。

于 2012-07-06T02:38:43.650 に答える
0

wファイルポインタは、常にあなたがすでに読んだものを超えて進んでいます。

于 2012-07-06T02:10:12.317 に答える