混合ifstream getline和>>

时间:2012-02-17 22:15:34

标签: c++ io

使用>>输入float值后,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;

编辑:包含ignore()会产生以下错误:

   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

1 个答案:

答案 0 :(得分:2)

首先,开始使用std::stringstd::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!,则不应忽略任何内容,而应定义用于解析文档的正确语法。