C ++读取文件

时间:2012-07-06 02:08:32

标签: c++ input

如果我打开一个新文件进行输入,我在while循环之外调用input >> listSize;,然后继续调用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

3 个答案:

答案 0 :(得分: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.
      }
 }

答案 1 :(得分: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 ++的方便花花公子istream_iterator来简化代码:

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

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

答案 2 :(得分:0)

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