2010-12-10 62 views
1

假設我想從控制檯讀取行並將它們放入容器中,直到用戶輸入空行。不過,我不想讓那空白的行結束在我的容器中。我能想到的五種不同的解決方案:直到用戶輸入空白行

一)從迴路斷線

std::vector<std::string> container; 
for (; ;) 
{ 
    std::string line = get_input(); 
    if (line.empty()) break; 
    container.push_back(line); 
} 

B)循環前閱讀和內環路

std::vector<std::string> container; 
std::string line = get_input(); 
while (!line.empty()) 
{ 
    container.push_back(line); 
    line = get_input(); 
} 

C)解讀爲循環條件的一部分,分配版本

std::vector<std::string> container; 
std::string line; 
while (!(line = get_input()).empty()) 
{ 
    container.push_back(line); 
} 

d)作爲循環條件的一部分讀取,序列版本

std::vector<std::string> container; 
std::string line; 
while (line = get_input(), !line.empty()) 
{ 
    container.push_back(line); 
} 

E)讀得太多,循環之後

std::vector<std::string> container; 
std::string line; 
do 
{ 
    line = get_input(); 
    container.push_back(line); 
} 
while (!line.empty()); 
container.pop_back(); 

所以刪除它,你更喜歡哪解決,爲什麼?初學者最容易理解哪一個?

回答

2

我更喜歡(a)。簡單而且很自然地閱讀。 (b)重複獲取輸入的行。 (c)和(d)都使用可能會讓初學者感到困惑的語法(具體來說,逗號不在for語句或定義中,並且在條件中賦值)。儘管如此,我可能更喜歡(c)而不是(d)。 (e)效率不高。如果最後的push_back導致重新分配,該怎麼辦?

0

正如你可能從我的期望,我建議代理:

class non_blank { 
    std::string data; 

    friend operator>>(std::istream &is, non_blank &n) { 
     std::string temp; 

     std::getline(is, temp); 

     // I'm not writing this from home, so I'm going from memory. 
     // The following line is probably a little wrong. 
     is.setbit(std::ios::fail, temp.length()!=0); 
     return is; 
    } 
    operator std::string() { return data; } 
}; 

non_blank line; 
while (infile >> line) 
    container.push_back(line); 

這有一個副作用,即可能是意想不到的,但:因爲它希望讀取非空行,它認爲空白行是一個失敗的轉換 - 這意味着之後從流中讀取更多,您必須清除流的失敗位。由於它通過設置流的失敗位而工作,因此您還應該能夠使用std::copy來讀取輸入,並在轉換失敗時停止。

+0

這樣的方式,矯枉過正他是什麼試圖完成。 – 2010-12-10 14:21:33

+0

我想這取決於你需要這麼做的頻率 - 如果你只使用它一次,我可以看到你可以爭辯說它有點矯枉過正,但鑑於它只有大約10行代碼,我不要以爲你必須經常用它來證明它的合理性。 – 2010-12-10 14:25:05

2

我會使用方法「d」實際上:

- 它顯示在我認爲最好的是什麼做:首先讀取數據,那麼如果它不是「好」的數據(空行)停止閱讀數據。並且一切都處於預期的位置(檢查數據是否處於循環條件部分,處理循環體中的數據)

Mtheod「a」隱藏條件檢查&這是比較困難的),看看哪些「停止」的循環中的條件。

0

的修改至(d),使之更有效率,並遵循你正在嘗試做的更好。

std::vector<std::string> container; 
std::string line; 
do 
{ 
    line = get_input(); 
    if (!line.empty()) 
    { 
     container.push_back(line); 
    } 
    else 
    { 
     break; 
    } 
} 
while (true);