繁体   English   中英

如何从文件末尾读取第6个字符-ifstream?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM