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, или или ошибка (или может быть' '
) под некоторыми мейнфреймами ОС.
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.
Если мы пошли дальше, мы можем найти таблицу требований для fpos в разделе 27.4.3.2, где мы можем получить замыкание для типа streamoff, и здесь явное требование: q = p + o, поэтому класс fpos ДОЛЖЕН ОПРЕДЕЛИТЬ оператор + (смещение). Так как объект fpos также должен определять O (p) с возвращаемым типом OFF_T, который является внутренним типом, но также есть оператор, std :: streamoff имеет тип OFF_T, у нас есть замкнутый цикл для определения внутри стандарта для этой операции.
Так что эта операция должна быть четко определена.
Другие мнения приветствуются.
Сначала перейдите в конец файла: is.seekg (0, ios::end);
, затем сохраните позицию: file_end_position = is.tellg();
, Теперь перейдем к этой позиции: is.seekg (file_end_position-6, ios::end);
и прочитайте шестой символ с конца: 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;
}