std::ios_base::binary
сам по себе не является действительным открытым моментом для std::basic_fstream
. Допустимые комбинации OpenMode можно найти в таблице 132:

Конструктор std::basic_fstream
и способ его open()
как вперед метод open()
на внутренней std::basic_filebuf
через rdbuf()->open(s, mode)
, где mode
является OpenMode. Как видно из таблицы, mode
(где режим ios_base::binary
) сам по себе не является допустимым. Когда буфер файла определяет это открыть файл не удалось:
НТБ modstr
определяется из mode & ~ios_base::ate
, как указано в таблице 132. Если mode
не какая-то комбинация флагов, показанных в таблице, то открытое терпит неудачу.
Причина mode
не побитовое-с out | in
AND-ed при открытии файла, потому что это не ясно, хотите ли вы использовать поток для ввода или вывода (это предполагает, что вы знаете, что вы хотите). Поскольку режим не является допустимой комбинацией флагов, std::basic_filebuf::open()
возвращает нулевой указатель. Это поднимается потоком, который в свою очередь вызывает setstate(std::ios_base::failbit)
.
[..] звонки rdbuf()->open(s, mode)
. Если эта функция возвращает нулевой указатель, вызывает setstate(failbit)
.
Когда поток находится в состоянии сбоя, его методы tell
возвращают -1
. Вот почему вы получаете 0
при вычитании.
Это правильный путь, чтобы открыть его, если все, что вы хотите, размер:
std::fstream f1("file1", std::ios_base::in | std::ios_base::ate | std::ios_base::binary);
std::cout << f1.tellg();
Это честно расстраивает меня, как люди могут писать код, который не проверяет наличие ошибок. Просто почему?! –