Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Лишний байт при записи структуры в файл

#cpp #c #файлы #вывод #запись


Откуда берется лишний байт?

#include 
#include 
#include 

#pragma pack(push, 1)
typedef struct {
    int a;
    float b;
} structEx;
#pragma pack(pop)
using namespace std;
int main()
{
    {
        structEx x;
        x.a = 2;
        x.b = 4.2;
        ofstream fout("Text1.txt");
        for (int i = 0; i < 10; i++) {
            x.a += 3;
            x.b += 0.5;
            fout.write((char *)&x, sizeof(x));
        }
        fout.close();
    }
    {
        structEx x;
        x.a = 2;
        x.b = 4.2;
        ofstream fout("Text2.txt");
        for (int i = 0; i < 10; i++) {
            x.a += 3;
            x.b += 0.51;
            fout.write((char *)&x, sizeof(x));
        }
        fout.close();
    }
    return 0;
}


Text1.txt при x.b += 0.5;

// 0500 0000 6666 9640 0800 0000 6666 a640
// 0b00 0000 6666 b640 0e00 0000 6666 c640
// 1100 0000 6666 d640 1400 0000 6666 e640
// 1700 0000 6666 f640 1a00 0000 3333 0341
// 1d00 0000 3333 0b41 2000 0000 3333 1341


Text2.txt при x.b += 0.51;

// 0500 0000 52b8 9640 0800 0000 3e0d 0aa7
// 400b 0000 002a 5cb7 400e 0000 0016 aec7
// 4011 0000 0002 00d8 4014 0000 00ee 51e8
// 4017 0000 00da a3f8 401a 0000 00e3 7a04
// 411d 0000 00d9 a30c 4120 0000 00cf cc14
// 41

    


Ответы

Ответ 1



По умолчанию потоки открываются в текстовом режиме (при котором символ \n преобразуется в Windows в пару \r\n), так что надо просто вместо ofstream fout("Text.txt"); написать ofstream fout("Text.txt", ios::binary); Компьютер не понимает разницы между бинарными и текстовыми данными - для него все это один поток байтов, а что они означают - ему безразлично. Когда вы открываете файл для записи в текстовом режиме в соответствующей операционной системе, это означает команду "пиши байты как есть, но если встретишь байт 0x0A - запиши пару 0x0D 0x0A". А при чтении - наоборот - "если встретишь эту пару байт - то в память заноси только один 0x0A".

Ответ 2



Под операционной системой Linux данный код выполняется корректно и не производит добавление лишних байт в файл. root@debian:/# g++ 1.cpp root@debian:/# ./a.out root@debian:/# hexdump -C Text1.txt 00000000 05 00 00 00 66 66 96 40 08 00 00 00 66 66 a6 40 |....ff.@....ff.@| 00000010 0b 00 00 00 66 66 b6 40 0e 00 00 00 66 66 c6 40 |....ff.@....ff.@| 00000020 11 00 00 00 66 66 d6 40 14 00 00 00 66 66 e6 40 |....ff.@....ff.@| 00000030 17 00 00 00 66 66 f6 40 1a 00 00 00 33 33 03 41 |....ff.@....33.A| 00000040 1d 00 00 00 33 33 0b 41 20 00 00 00 33 33 13 41 |....33.A ...33.A| 00000050 root@debian:/# hexdump -C Text2.txt 00000000 05 00 00 00 52 b8 96 40 08 00 00 00 3e 0a a7 40 |....R..@....>..@| 00000010 0b 00 00 00 2a 5c b7 40 0e 00 00 00 16 ae c7 40 |....*\.@.......@| 00000020 11 00 00 00 02 00 d8 40 14 00 00 00 ee 51 e8 40 |.......@.....Q.@| 00000030 17 00 00 00 da a3 f8 40 1a 00 00 00 e3 7a 04 41 |.......@.....z.A| 00000040 1d 00 00 00 d9 a3 0c 41 20 00 00 00 cf cc 14 41 |.......A ......A| 00000050 Как уже ответили, проблема происходит под некоторыми устаревшими операционными системами, сам же код ошибки не содержит. Не ищите ошибку там, где ее нет.

Комментариев нет:

Отправить комментарий