虽然derpface 的答案绝对正确,但它经常返回意想不到的结果。这样做的原因是,至少在我的操作系统(Mac OSX 10.9.5)上,许多文本编辑器使用“结束行”字符终止其文件。
例如,当我打开 vim 时,只输入单个字符 'a'(不返回),然后保存,文件现在将包含(十六进制):
61 0A
其中 61 是字母“a”,0A 是行尾字符。
这意味着derpface的代码将对此类文本编辑器创建的所有文件返回一个空字符串。
虽然我当然可以想象以“结束行”结尾的文件应该返回空字符串的情况,但我认为在处理常规文本文件时忽略最后一个“结束行”字符会更合适;如果文件以“end line”字符终止,我们会正确地忽略它,如果文件没有以“end line”字符终止,我们不需要检查它。
我忽略输入文件最后一个字符的代码是:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
int main() {
std::string result = "";
std::ifstream fin("test.txt");
if(fin.is_open()) {
fin.seekg(0,std::ios_base::end); //Start at end of file
char ch = ' '; //Init ch not equal to '\n'
while(ch != '\n'){
fin.seekg(-2,std::ios_base::cur); //Two steps back, this means we
//will NOT check the last character
if((int)fin.tellg() <= 0){ //If passed the start of the file,
fin.seekg(0); //this is the start of the line
break;
}
fin.get(ch); //Check the next character
}
std::getline(fin,result);
fin.close();
std::cout << "final line length: " << result.size() <<std::endl;
std::cout << "final line character codes: ";
for(size_t i =0; i<result.size(); i++){
std::cout << std::hex << (int)result[i] << " ";
}
std::cout << std::endl;
std::cout << "final line: " << result <<std::endl;
}
return 0;
}
将输出:
final line length: 1
final line character codes: 61
final line: a
在单个“a”文件上。
编辑:如果文件太大(> 2GB),if((int)fin.tellg() <= 0){ 行实际上会导致问题,因为tellg 不仅仅返回文件开头的字符数(tellg() function give wrong size of file?)。最好分别测试文件的开头fin.tellg()==tellgValueForStartOfFile 和错误fin.tellg()==-1。 tellgValueForStartOfFile 可能为 0,但更好的确保方法可能是:
fin.seekg (0, is.beg);
tellgValueForStartOfFile = fin.tellg();