Режим открытия файла в C++

Подскажите как узнать в каком режиме открыт файл: в текстовом или в двоичном.

У меня есть функция которая получает аргумент типа ostream& ostrm. Мне надо внутри функции узнать в каком режиме открыт файл. Потому что в зависимости от режима функция должна по разному работать.

Вроде как нет никаких различий текстового от двоичного файлов, поэтому никак не проверить. Передавай режим открытия и всё.

Различие есть. Если unsigned int a = 4294967295, то вывод a в файл в текстовом режиме даст строку в 10 байт «4294967295», а в двоичном выведет 4 байта FF FF FF FF.

Передать режим открытия не могу. operator<< принимает только два аргумента. Через глобальную переменную тоже не хотелось бы.

Должен же быть у открытого потока какой то флаг: делать ему преобразование в текст или не делать?!

Находится в защищенном свойстве _M_mode. https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.0/fstream-source.html — смотри 99-ю строку.

Рекомендую в функцию передавать флаг binary — true/false. Это будет более явным решением, да и доступ к protected-свойству класса могут получать только его потомки.

печалька

Рекомендую в функцию передавать флаг binary — true/false.

не получится

Передать режим открытия не могу. operator<< принимает только два аргумента. Через глобальную переменную тоже не хотелось бы.

А зачем твоему оператору знать, в каком режиме он пишет данные в файл? По логике, об этом должен заботиться код, использующий оператор.

Задача оператора << — записать данные в поток. Неважно, какие, и неважно, в каком режиме сейчас открыт файл. О целостности данных должен заботиться вызывающий код.

И да, если сделать его дружественным, то доступ к protected-свойству _M_mode также можно получить.

А зачем твоему оператору знать, в каком режиме он пишет данные в файл? По логике, об этом должен заботиться код, использующий оператор.

В общем то да. Только вот такой код

ofstream &operator<<(ofstream &strm, const MyClass& m)
{
    strm << m.i;   // i - integer
    return strm;
}
// ...
ofstream out("data.dat", ios_base::out | ios_base::binary);
out << mclass;
out.close();

все равно в файл выводит строковое представление числа несмотря на флаг ios_base::binary.

Если бы можно было внутри функции определить, что поток открыт в двоичном режиме, то можно было бы использовать ф-цию write, которая пишет данные в поток в двоичном режиме.

И да, если сделать его дружественным, то доступ к protected-свойству _M_mode также можно получить.

а это не понял. Кого кому сделать дружественным? И главное как?

Логикой записи данных должен заниматься basic_ofstream, а не твой класс.

Расширяй ofstream, чтобы изменить логику записи данных в поток либо для создания доступа к режиму записи.

Как-то так.

class mystream : public ofstream
{
    public:

    std::ios::openmode mode()
    {
        return _M_filebuf._M_mode;
    }
};

все равно в файл выводит строковое представление числа несмотря на флаг ios_base::binary.

потому что для записи в бинарном виде используется write, а не operator<<

std::ostream::operator<<

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.