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

时间:2012-09-05 07:49:46

标签: c++ file-io 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
我哪里错了?

5 个答案:

答案 0 :(得分:6)

在文本文件中寻找任意位置是未定义的行为。 在实践中,它可能会在各种Unices下工作,但不会在哪里工作 其他。如果以二进制模式打开文件,则搜索是合法的。 形式上,如果您以二进制模式打开文件,您可能会得到额外的nul 最后的字节,但在实践中,这不是今天的问题。如果你 然而,在二进制模式下打开它,你可能会看到别的东西而不是 数据中'\n';例如,在Windows下,你会看到这两个 字符序列0x0D, 0x0A

当然,在您的代码中,您从一开始就寻求,而不是从 结束。这也是未定义的行为,但大多数时候,它会 只要你在第一行寻找工作。

最后,您显示的数据中的第六个字符是a 你写的时候'2',而不是'0'。但当然,除了以外的系统 Unix,你可以很容易地看到别的东西(或者得到一个错误):可能是一个 Windows下的'.'或某个大型机操作系统下的错误(或者可能是“' '”。

答案 1 :(得分:4)

myfile.seekg (6, std::ios::beg);

这里你从开始移动6个字符,而不是从开始移动。只需使用

myfile.seekg (-6, std::ios::end);

答案 2 :(得分:1)

第一个搜索跳到最后,第二个搜索跳到开头+6。

使用:

 myfile.seekg(-6, std::ios::end);

答案 3 :(得分:1)

您可以尝试通过文件末尾的tellg()确定文件的完整大小,然后减去您的数字,并根据&gt;验证它。 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,我们有一个闭环到标准内的定义对于这个操作。

所以这个操作应该很明确。

欢迎其他意见。

答案 4 :(得分:0)

首先,转到文件末尾: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;
}