2012-07-06 113 views
1

如果我打开一个新文件进行输入,并且在一个while循环之外呼叫input >> listSize;,然后继续调用input >> anothervariable它会自动通过文件进行还是会再次读取第一行?C++通过文件读取

例子:

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 

回答

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 s至更简化的代码:

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

这就是它 - 它定义了矢量和从输入文件初始化它,都在一个(相当)操作简单。

0

Thew文件指针始终以先进过去你已经阅读。

+0

太棒了,谢谢。 – 2012-07-06 02:13:07

+0

如果我使用'getline()',是否也会持有?我认为使用行分隔符会更容易。 – 2012-07-06 02:13:55

+0

是的。 getline将始终读取下一个换行符,并将指针留在那里。 – stark 2012-07-06 02:55:05

3

从流中读取数据时使用。
接下来的时间会从最后一个点读读“先进”

虽然流运算符>>将跳过出发的空白,但如果你的输入将无法读取对象之后白色空间(可以是一个痛苦线方向,因为你没有看到新的线条)。

来解决这个问题的最好办法是在一次明确读线然后解析线:

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. 
     } 
} 
+0

只有在出现错误时才会检测到EOF ...没有理由将其视为单独的案例。 – 2012-07-06 02:15:39