[英]How to read the 6th character from the end of the file - ifstream?
void maintainFileName ()
{
std :: ifstream myfile;
myfile.open ("zoomLevels.txt");
if (myfile.is_open ())
{
// Move to end of the file,
myfile.seekg (0, std::ios::end);
// and then six characters back to pick up the last file number.
myfile.seekg (6, std::ios::beg);
int len = 1;
char *t = new char[len];
myfile.read(t, len);
qDebug () << "\nt: " << *t << "\n";
}
else
{
qDebug () << "\nsorry";
}
}
该文件包含以下内容:
78.8115,29.582,1,01.rda
78.8115,29.582,2,02.rda
76.3671,30.2201,1,11.rda
76.3671,30.2201,2,12.rda
78.1908,30.3007,1,01.rda
78.1908,30.3007,2,02.rda
77.3284,29.1415,1,01.rda
77.3284,29.1415,2,02.rda
77.3064,29.1655,1,01.rda
77.3064,29.1655,2,02.rda
该函数返回的值为5
,而末尾的第六个字符为0
!
我要去哪里错了?
在文本文件中寻找任意位置是未定义的行为。 实际上,它可能会在各种Unices下工作,但在其他任何地方都不会。 如果以二进制模式打开文件,则查找是合法的。 正式地,如果以二进制模式打开文件,则最后可能会得到额外的nul字节,但是实际上,今天这不是问题。 但是,如果以二进制模式打开它,则可能会在数据中看到其他内容,而不是'\\n'
。 例如,在Windows下,您会看到两个字符序列0x0D, 0x0A
。
当然,在您的代码中,您是从头开始,而不是从头开始。 这也是未定义的行为,但是在大多数情况下,只要您在第一行中进行搜索,它便会起作用。
最后,在您显示的数据中,从末尾开始的第六个字符是'2'
,而不是'0'
。 但是,当然,在非Unix的系统上,您很容易看到其他内容(或得到错误):可能是'.'
在Windows下,或者在大型机OS下出现错误(或者可能是“ ' '
)。
myfile.seekg (6, std::ios::beg);
在这里你从一开始移动6个字符,不计入开始时。 只需使用
myfile.seekg (-6, std::ios::end);
第一个搜寻跳到结尾,第二个搜寻跳到开头+ 6。
采用:
myfile.seekg(-6, std::ios::end);
您可以尝试通过文件末尾的tellg()确定文件的完整大小,然后减去数字,对> 0进行验证,然后再次查找。 如果尝试此操作,还应确保以二进制模式打开文件(我记得,可能存在缺陷)
myfile.seekg (0, ios::end);
// You have to ensure, myfile.tellg() > 6
myfile.seekg ( myfile.tellg() - 6, ios:beg );
编辑:
seekg将类型std :: streamoff作为偏移量。
该标准(ISO / IEC 14882:2003)说了很多人讨论的有关此“问题”的一些非常有趣的内容。
在第27.2节中。 转发声明,streampos是fpos类。
如果进一步,我们可以在27.4.3.2节找到fpos的需求表,在这里可以得到streamoff类型的闭包,这里的显式要求是:q = p + o,因此fpos类必须定义一个运算符+(偏移量)。 由于fpos对象还必须使用内部类型的返回类型OFF_T定义O(p),但也有一条语句,因此std :: streamoff的类型为OFF_T,我们在标准内部对定义进行了闭环处理为此操作。
因此,应明确定义此操作。
欢迎其他意见。
首先,转到文件末尾: is.seekg (0, ios::end);
,然后保存位置: file_end_position = is.tellg();
。 现在跳转到该位置: is.seekg (file_end_position-6, ios::end);
,并从末尾读取第6个字符: is.read (buf,1);
#include <iostream>
#include <fstream>
using namespace std;
int main () {
int file_end_position;
ifstream is;
is.open ("test.txt", ios::binary );
// get size of file:
is.seekg (0, ios::end);
file_end_position = is.tellg();
is.seekg (0, ios::beg);
//go to the end of the file -6
is.seekg (file_end_position-6, ios::end);
char buf[1];
// read the 6th character from the end of the file
is.read (buf,1);
is.close();
delete[] buffer;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.