2012-07-06 146 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