Учитывая следующий код:
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};
Режим по умолчанию, используемый конструктором потока: ios_base::out
, Как нет явного text
флаг режима, это означает, что поток открывается в текстовом режиме. Текстовый режим влияет только на системы Windows, где он преобразует \n
символы в пары CR / LF. В системах POSIX это не имеет никакого эффекта, и текстовый и двоичный режимы являются синонимами в этих системах.
Когда я запускаю ваш код в Windows, используя g++
а также libstdc++
, я получаю следующий результат:
expect: 32
file size: 33
Так что проблема не в компиляторе, а в ОС.
В то время как C ++ использует один символ \n
для представления строки, заканчивающейся строкой, Windows использует два байта 0x0D
а также 0x0A
для строки, заканчивающейся в файле. Это означает, что если вы пишете строку в файл в текстовом режиме, все вхождения одного символа \n
записаны с использованием этих двух байтов. Вот почему вы получаете дополнительные байты в размере файла ваших примеров.