Определен ли режим по умолчанию для реализации ofstream?

Учитывая следующий код:

std::ofstream stream("somefile");

if (!stream)
{
return 1;
}

При вызове .записывать(….) и используя STDC ++ а также Libc ++ поток в двоичном режиме (std::ios::binary).

Однако при использовании MSVC (2015 / 2017RC1) кажется, что это в текстовом режиме или что-то странное, потому что результирующий файл больше, чем то, что написано на самом деле.

Но если я явно установлю режим std::ios::binary MSVC ведет себя аналогично std::ofstream реализации других стандартных библиотек, упомянутых ранее.


Пример кода:

#include <vector>
#include <cstdio>
#include <fstream>

std::size_t fsz(const char* filename) {
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return static_cast<std::size_t>(in.tellg());
}

int main() {
std::ofstream stream("filename");

if (!stream)
return 1;

std::vector<unsigned long long int> v = {0x6F1DA2C6AC0E0EA6, 0x42928C47B18C31A2, 0x95E20A7699DC156A, 0x19F9C94F27FFDBD0};

stream.write(reinterpret_cast<const char*>(v.data()),v.size() * sizeof(unsigned long long int));

stream.close();

printf("expect: %d\n", v.size() * sizeof(unsigned long long int));
printf("file size: %d\n", fsz("filename"));

return 0;
}

Вывод приведенного выше кода при запуске с msvc:

expect: 32
file size: 33

Вывод приведенного выше кода при запуске с libc ++, stdc ++:

expect: 32
file size: 32

Разница может стать намного больше, это зависит от того, сколько данных записано и содержание данных.

в конце мой вопрос все тот же, это неопределенное или неопределенное поведение?


изменение вышеуказанного вектора на следующий делает пример более очевидным в отношении того, что происходит.

std::vector<unsigned long long int> v = {0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A, 0x0A0A0A0A0A0A0A0A};

1

Решение

Режим по умолчанию, используемый конструктором потока: ios_base::out, Как нет явного text флаг режима, это означает, что поток открывается в текстовом режиме. Текстовый режим влияет только на системы Windows, где он преобразует \n символы в пары CR / LF. В системах POSIX это не имеет никакого эффекта, и текстовый и двоичный режимы являются синонимами в этих системах.

4

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

Когда я запускаю ваш код в Windows, используя g++ а также libstdc++, я получаю следующий результат:

expect: 32
file size: 33

Так что проблема не в компиляторе, а в ОС.

В то время как C ++ использует один символ \n для представления строки, заканчивающейся строкой, Windows использует два байта 0x0D а также 0x0A для строки, заканчивающейся в файле. Это означает, что если вы пишете строку в файл в текстовом режиме, все вхождения одного символа \n записаны с использованием этих двух байтов. Вот почему вы получаете дополнительные байты в размере файла ваших примеров.

3

По вопросам рекламы [email protected]