混合ifstream getline和>>

Mixing ifstream getline and >>

本文关键字:gt ifstream getline 混合      更新时间:2023-10-16

使用>>输入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

首先,开始使用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!,你不应该忽略它,而是定义一个合适的语法来解析文档。