2012-02-17 35 views
0

使用>>輸入float值後,getline停止正常工作並讀取垃圾。我怎樣才能避免這種情況?混合ifstream getline和>>

string settingsFile = "TerrainSettings.txt"; 

    ifstream settingsStream; 

    settingsStream.open(settingsFile.data()); 
    assert (settingsStream.is_open()); 

    string line; 

    getline(settingsStream,line); // fine here 
    getline(settingsStream,line); // fine here 
    getline(settingsStream,line); // fine here 

    float frequency; 
    float octaves; 
    float amplitude; 

    settingsStream>>frequency; // fine here 

    getline(settingsStream,line); // here it gets trash, why? 

    settingsStream>>octaves; // trash 

    getline(settingsStream,line); 

    settingsStream>>amplitude; 

編輯:忽略的包容(),生成下面的錯誤:

settingsStream>>frequency; 

    settingsStream.ignore(256,'\n'); 

    getline(settingsStream,line); // fine here 

    settingsStream>>octaves; // trash here 

    getline(settingsStream,line); 

    settingsStream>>amplitude; 

樣本輸入:

所有的
/*Settings for Terrain Rendering, please input values on their respective lines*/ 
/**/ 
Frequency:     
24 
Octaves:     
120 
Amplitude:     
1.25 
+0

您能否提供一個示例輸入? – 2012-02-17 22:16:45

回答

2

首先,開始使用std::string S和std::getline。其次,搗毀的原因是緩衝區中仍然有一個換行符。如果您希望用戶一次輸入一行數值,則應該使用istream::ignore來跳過一切,直到包括下一個換行符。例如:

std::string s; 
float f; 
std::cin >> f; 
std::cin.ignore(big_num, '\n'); 
std::getline(std::cin, s); 

應該是什麼big_num取決於你對輸入的期望。如果您不介意寫很多內容並希望保持安全,請使用std::numeric_limits<std::streamsize>::max()。如果你確實介意寫很多東西,可以隨時隨地使用適合的類型。

例如,上面的代碼將解析以下內容,以便f = 5.0fs = Hello!

5 
Hello! 

然而,它將解析如下完全相同的方式:

5 Hi! 
Hello! 

如果您想保留Hi!,你不應該忽視的東西,而是定義了一個正確的語法,你」將用於解析文檔。

+0

謝謝,但你回答了未經編輯的問題。我在發佈之前將代碼更改爲std:getline和std :: string秒。換行符的單個忽略在下面的幅度讀取上會產生垃圾。我會重新編輯問題。 – andandandand 2012-02-17 22:43:28

+0

@omgzor:你必須忽略每一次讀取float和getline之間的內容。以下是一個解析給定輸入的例子:http://ideone.com/INel1 – 2012-02-17 22:47:38

+0

謝謝,這很好。 – andandandand 2012-02-18 02:13:12