Как прочитать 6-й символ из конца файла — 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!
Куда я иду не так?

0

Решение

Поиск произвольной позиции в текстовом файле — неопределенное поведение.
На практике это, вероятно, будет работать под различными Unices, но не где
остальное. Если вы откроете файл в двоичном режиме, поиск будет законным.
Формально, если вы откроете файл в двоичном режиме, вы можете получить дополнительные nul
байтов в конце, но на практике это не проблема сегодня. если ты
откройте его в двоичном режиме, однако вместо
'\n' в данных; под Windows, например, вы увидите два
последовательность символов 0x0D, 0x0A,

Конечно, в вашем коде вы ищете с самого начала, а не с
конец. Это также неопределенное поведение, но в большинстве случаев
работать до тех пор, пока вы ищете в первой строке.

И, наконец, шестой символ в конце данных, которые вы показываете, является
'2'не '0', как ты пишешь. Но, конечно же, в системах, отличных от
Unix, вы можете легко увидеть что-то еще (или получить ошибку): вероятно,
'.' под Windows, или или ошибка (или может быть' ') под некоторыми мейнфреймами ОС.

6

Другие решения

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

здесь вы двигаетесь 6 символов от начало, а не к начало. Просто используйте

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

Первый поиск пропускается до конца, а второй — до начала + 6.

Использование:

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

Вы можете попытаться определить полный размер файла с помощью 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, у нас есть замкнутый цикл для определения внутри стандарта для этой операции.

Так что эта операция должна быть четко определена.

Другие мнения приветствуются.

1

Сначала перейдите в конец файла: 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;
}
0
По вопросам рекламы [email protected]