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>
};

然后,我将编写一个函数来从文件中读取其中一项:

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++ 的handy-dandyistream_iterator来进一步简化代码:

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

就是这样——它定义了向量并从输入文件初始化它,所有这些都在一个(相当)简单的操作中完成。

于 2012-07-06T02:38:43.650 回答
0

Thew 文件指针总是超过你已经读过的。

于 2012-07-06T02:10:12.317 回答