Файловые потоки: read, write. Странные вещи происходят.
От: Ravshan  
Дата: 13.05.07 07:46
Оценка:
Сохраняю объекты класса address в одном проекте:
#include "..\address.h"
int main () {
    //
    SetConsoleOutputCP(1251);
    char* filename="..\\write.txt";
    address a("Иванов","Ленина",1),b("Petrov","gg",2),c("3","3",3);
    filebuf buf;
    buf.open(filename,ios::out|ios::binary);    
    ostream out(&buf);
    out.write((char*)&a, sizeof(address));
    out.write((char*)&b, sizeof(address));
    out.write((char*)&c, sizeof(address));
    buf.close();
    return 0;
}


Считываю в другом проекте:
#include "..\address.h"
int main () {
    //
    SetConsoleOutputCP(1251);
    char* filename="..\\write.txt";
        in.open(filename,ios::in | ios::binary);
    address a,b,c;
    in.read((char*)&a,sizeof(address));
    in.read((char*)&b,sizeof(address));
    in.read((char*)&c,sizeof(address));
    a.Show();
    b.Show();
    c.Show();
    in.close();
    return 0;
}


Когда вывожу в первых двух полях которые string абракадабра, а в третьем, которое инт все нормально. Студия Visual Studio 6. Когда записываю и считываю в одном проекте все нормально. И в 2005 студии в разных все нормально работает. Но нужно сделать в 6 и в разных. Как?
Re: Файловые потоки: read, write. Странные вещи происходят.
От: LuciferMoscow Россия  
Дата: 13.05.07 07:56
Оценка:
Здравствуйте, Ravshan, Вы писали:

R>Когда вывожу в первых двух полях которые string абракадабра,

Это std::string? Тогда все понятно. Абракадабра и должна быть
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[2]: Файловые потоки: read, write. Странные вещи происходя
От: Ravshan  
Дата: 13.05.07 07:59
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:
LM>Это std::string? Тогда все понятно. Абракадабра и должна быть
Но 2005 работает, и в 6 когда в одном проекте работает. Как исправить-то?
Re[3]: Файловые потоки: read, write. Странные вещи происходя
От: LuciferMoscow Россия  
Дата: 13.05.07 08:09
Оценка:
Здравствуйте, Ravshan, Вы писали:

LM>>Это std::string? Тогда все понятно. Абракадабра и должна быть

R>Но 2005 работает, и в 6 когда в одном проекте работает. Как исправить-то?
Значит тебе везло. Реализация std::string не определена в стандарте. Одна из возможных(сильно упрощенная и кастрированная)

class string
{
private:
char* buffer_;
size_t bufSize_;
public:
std::string(const char* initString)
{
bufSize_=strlen( initString )+1;
buffer_ = new char[ bufSize_ ];
strcpy( initString, buffer );
}
};
Что будет при твоем виде загрузки такой строки понимаешь?

P.S. То, что std::string — typedef для std::basic_string<......> ЗНАЮ. Просто усложнять не хотел
P.S.S. Как нарисовать тут простое и правильное решение- не знаю(есть желание послать автора темы к бустовой сериализации)
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re: Файловые потоки: read, write. Странные вещи происходят.
От: Кодт Россия  
Дата: 15.05.07 09:31
Оценка:
Здравствуйте, Ravshan, Вы писали:

R>    out.write((char*)&a, sizeof(address));

Убийца памяти!
Ты надеешься, что если запишешь побайтово указатель, а потом прочтёшь те же байты, то они будут указывать на то же самое содержимое?

R>Когда вывожу в первых двух полях которые string абракадабра, а в третьем, которое инт все нормально. Студия Visual Studio 6. Когда записываю и считываю в одном проекте все нормально. И в 2005 студии в разных все нормально работает. Но нужно сделать в 6 и в разных. Как?


Это связано с тем, что в какой-то из версий STL строка содержит внутри себя короткий буфер — это позволяет избежать лишних выделений памяти. А в другой не содержит!

Нужно сделать:
полноценную, а не халтурную функцию сериализации для класса address.
Представь себе, что считывать его будет не сишная программа, а вообще бейсиковая. Вот и обеспечь такой формат файла, который не зависит от языка.

В простейшем виде:
ostream& operator << (ostream& ost, address const& a)
{
    ost << a.name << "\n"; // по одному полю на линию текста
    ost << a.street << "\n";
    ost << a.house << "\n";
    return ost;
}
istream& operator >> (istream& ist, address& a)
{
    getline(istr, a.name); // считываем линию целиком (обычный istr >> a.name считает до пробела)
    getline(istr, a.street);
    ist >> a.house;
    return ist;
}

В навороченном — посмотри, например, boost::serialization
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: Файловые потоки: read, write. Странные вещи происходя
От: Ravshan  
Дата: 15.05.07 20:10
Оценка:
Здравствуйте, Кодт, Вы писали:

Спасибо за емкий ответ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.