1
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
我哪里错了?

4

5 回答 5

7

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

当然,在您的代码中,您是从头开始寻找,而不是从头开始寻找。这也是未定义的行为,但大多数情况下,只要您在第一行寻找,它就会起作用。

最后,在您写的数据中,您显示的数据中倒数第六个字符是 a '2',而不是 a '0'。但是,当然,在 Unix 以外的系统上,您可能很容易看到其他内容(或出现错误):可能是 '.'Windows 下的 a,或' '某些大型机操作系统下的错误(或可能是 ' )。

于 2012-09-05T08:02:55.333 回答
4
myfile.seekg (6, std::ios::beg);

在这里,您开头移动了 6 个字符,而不是开头移动。只需使用

myfile.seekg (-6, std::ios::end);
于 2012-09-05T07:51:22.173 回答
2

您可以尝试通过文件末尾的 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 我们有一个闭环到标准内的定义对于这个操作。

所以这个操作应该很好定义。

欢迎其他意见。

于 2012-09-05T08:12:00.913 回答
1

第一次搜索跳到结尾,第二次跳到开头 + 6。

采用:

 myfile.seekg(-6, std::ios::end);
于 2012-09-05T07:53:09.137 回答
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;
}
于 2012-09-05T10:53:59.373 回答