就输入文件读取而言,
-
我发现
for (i = 0; !inStream.eof() ; i++) inStream >> input[i];
如果文件末尾有"新行",则尝试再读取一次。
for (i=0; inStream >> input[i]; i++ ) ;
无论文件末尾是否有新行,似乎都有效。
有没有其他巧妙的解决方案来处理文件末尾的"新行"?
-
在c中,我写
FILE *fp = fopen("file", "r") ; for (i=0; fscanf(fp, "%d", & input[i]) > 0 ; i++ ) ;
有什么方法可以将fscanf
与c++输入文件流一起使用而不使用fopen()
吗?
getline
函数。以下是cplusplus.com 的一个最小示例
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << 'n';
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
有什么方法可以将
fscanf
与c++输入文件流一起使用吗?
可能。g++
和Visual Studio都有自己的扩展,使其成为可能。如果你发现这样的可能性,它们是非标准的,不可移植的。我建议你另辟蹊径。
如果你使用C++,尽量使用它。C
确实有fscanf
,看起来很整洁,但它是一个野兽。C++具有std::scanf
以实现可移植性,这也是一种野兽。如果你正在编程C++,就不要使用它。
你试图避免的问题
for (i = 0; !inStream.eof() ; i++) inStream >> input[i];
如果文件末尾有"新行",则尝试再次读取。
是由eof()
的使用不当引起的。eof()
在您尝试读取文件末尾之后返回true
。一个更好的循环看起来像:
for (i = 0; inStream >> input[i] ; i++);
注意到提取和条件是如何成为一体的吗?他们不是。提取首先发生,并返回提取中使用的流。流有一个bool
重载,它告诉它是否处于失败状态,这使得它非常适合这种检查:if(stream >> variable) { /* success */ } else { /* fail */ }
。
不过,只有当数组中有足够的条目来存储所有输入时,这才有效。你的循环没有检查这一点。如果使用vector
,则只需读取元素和push_back
即可使其长时间工作。如果你有一个固定的(相对较小的(尺寸,并执行上述操作,它最终会失败。