Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запись структуры в файл 
:(
    Опции темы
catherham
Дата 27.4.2011, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 7.7.2010

Репутация: нет
Всего: нет



Мне нужно записать структуру в файл.Структура выглядит так:
struct bite
 {
     unsigned char zn [256];
     string cod[256];
 };

Проблема в том, что массив zn[256] записывается полностью, а массив строк нет. Не записываются строки длиной в 16 символов и более.
Код функции
void writetable()
{
ofstream table("c:/hr.sh",ios::binary);
for( int k=0; k<=255; k++)
    {
        table.write(&znb.zn[k], 1);
        table.write(reinterpret_cast<char*>(&znb.cod[k]), 50);
    }
table.close();
}

PM MAIL   Вверх
boostcoder
Дата 27.4.2011, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(catherham @  27.4.2011,  19:17 Найти цитируемый пост)
string cod[256];


Цитата(catherham @  27.4.2011,  19:17 Найти цитируемый пост)
Проблема в том, что массив zn[256] записывается полностью, а массив строк нет. Не записываются строки длиной в 16 символов и более.

жесть...
работайте либо с массивом указателей на "строки", какие бы они у вас не были. либо откройте для себя сериализацию.

и обязательно поищите по слову "структур". ибо эта тема поднималась множество раз.


Это сообщение отредактировал(а) boostcoder - 27.4.2011, 20:59
PM WWW   Вверх
borisbn
Дата 27.4.2011, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(catherham @  27.4.2011,  19:17 Найти цитируемый пост)
table.write(reinterpret_cast<char*>(&znb.cod[k]), 50);

разберём:
znb.cod - массив, в котором хранятся классы (в нашем случае - string)
znb.cod[k] - один из элементов массива, т.е. одна строка
&znb.cod[k] - указатель на эту строку, т.е. адрес по которому расположен экземпляр класса string
reinterpret_cast<char*>(&znb.cod[k]) - преобразование этого указателя (мы помним, что он указывает на экземпляр класса string) к указателю на char, т.е. адрес остался тот же, но мы перестаём считать, что там лежит экземпляр класса string, и считаем, что там лежит char. Вопрос с чего это решено, что это (указатель на класс и указатель на char) - это одно и то же ?

и ещё. в файл, конечно, можно записать сначала один символ из массива unsigned char'ов, затем одну строку, и так далее, но тебе не кажется, что это не совсем логично ? Логичнее записать сначала весь массив unsigned char'ов, а затем все строки из массива строк.
Теперь дальше. В одной строке типа string может храниться от 0 до практически сколько угодно символов. Сколько из них ты хочешь записать в файл ? Если все, то как ты узнаешь при чтении, что одна строка уже закончилась и началась вторая ?
Пример:
1. Казнить нельзя
2. помиловать
в файле будет
Казнитьнельзяпомиловать

Добавлено через 4 минуты и 46 секунд
Цитата(catherham @  27.4.2011,  19:17 Найти цитируемый пост)
"c:/hr.sh"

вот это тож понравилось - эдакая помесь windows с linux.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
catherham
Дата 27.4.2011, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 7.7.2010

Репутация: нет
Всего: нет



Цитата

вот это тож понравилось - эдакая помесь windows с linux. 

У  меня в билдере только так работает.
Цитата

и ещё. в файл, конечно, можно записать сначала один символ из массива unsigned char'ов, затем одну строку, и так далее, но тебе не кажется, что это не совсем логично ? Логичнее записать сначала весь массив unsigned char'ов, а затем все строки из массива строк.

Не знаю, по моему вполне логично в данном случае. Зачем писать два цикла?.
Цитата

Теперь дальше. В одной строке типа string может храниться от 0 до практически сколько угодно символов. Сколько из них ты хочешь записать в файл ? Если все, то как ты узнаешь при чтении, что одна строка уже закончилась и началась вторая ?

Тут всё просто string это массив символов, часть массива занята остальные "" т.е. пустые. Я записываю и считываю по 50, в данном случае, байт. Таким образом:
"блабла /*здесь пусто.*/"
"блабла1 /*здесь пусто.*/"
Строки разные, но в итоге считываем 50, 10 из них,например, нас интересует остальное пусто, а вот это пусто может быть 40 или 39, не важно.
А вообще я ещё пробовал так  table.write(reinterpret_cast<char*>(&znb), sizeof(bite));
Такая же фигня, записывает и считывает нормально, но строки в 16 и более символов пустые.
Мне бы пример как сделали бы вы, можно на с, можно на с++


Это сообщение отредактировал(а) catherham - 27.4.2011, 22:21
PM MAIL   Вверх
borisbn
Дата 27.4.2011, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(catherham @  27.4.2011,  22:20 Найти цитируемый пост)
У  меня в билдере только так работает.

если ты имеешь в виду, что так не работает
"C:\hr.sh"
то это не в билдере, а во всём Си++ не работает. Обратный слеш нужно повторять, т.е. строка должна выглядеть так
"C:\\hr.sh"

Цитата(catherham @  27.4.2011,  22:20 Найти цитируемый пост)
Не знаю, по моему вполне логично в данном случае. Зачем писать два цикла?.

ну... дело твоё. а два цикла писать и не надо. первая запись должна быть такой
Код

table.write( znb.zn, sizeof( znb.zn ) );

а дальше уже цикл


Цитата(catherham @  27.4.2011,  22:20 Найти цитируемый пост)
Тут всё просто string это массив символов

ужЕ не верно. string - это класс. его внутренняя организация в общем случае вообще неизвестна. она может быть, например, такая
Код

class string {
    int count_of_chars_in_string;
    int allocated_chars;
    char * chars_ptr;
...
};

что будет, если ты возьмёшь адрес экземпляра такого класса ?
максимум, что ты имеешь право делать, так это попросить класс string вернуть тебе указатель chars_ptr (string::c_str()), который уже указывает на массив (вернее на начало массива) символов, причём количество символов в этом массиве = длина строки. и никак не больше (с чего бы это больше?)

Цитата(catherham @  27.4.2011,  22:20 Найти цитируемый пост)
часть массива занята остальные "" т.е. пустые

с чего ты это взял ?

Цитата(catherham @  27.4.2011,  22:20 Найти цитируемый пост)
Мне бы пример как сделали бы вы, можно на с, можно на с++

честно говоря, с этого нужно было начинать - мне нужно то-то, я сделал так-то, не работает, в чём проблема, можно пример как правильно...

ладно, с нравоучениями покончили. теперь к делу smile
Код

struct bite
 {
     unsigned char zn [256];
     //string cod[256]; <- проще всего заменить это на следующее
     char cod[ 256 ][ 50 ]; // 256 массивов !!! (не классов string), каждый из которых - массив char'ов размером 50
 };

void writetable()
{
    ofstream table( "c:\\hr.sh", ios::binary );
    if ( !table )
        return;
    table.write( znb.zn, sizeof( znb.zn ) );
    for( int k=0; k<256; k++ )
    {
        table.write( znb.cod[ k ], 50 );
    }
    //table.close(); необязательно, т.к. при выходе из ф-ции объект table будет разрушен, будет вызван его деструктор, который сам сделает close();
}

void readtable()
{
    ifstream table( "c:\\hr.sh", ios::binary );
    if ( !table )
        return;
    table.read( znb.zn, sizeof( znb.zn ) );
    for( int k=0; k<256; k++ )
    {
        table.read( znb.cod[ k ], 50 );
    }
}

как-то так. фух. устал. smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 27.4.2011, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(borisbn @  27.4.2011,  23:04 Найти цитируемый пост)
Обратный слеш нужно повторять

[оффтоп]не первый год это знаю, но до сих пор не могу запомнить кто из них прямой, а кто обратный smile[/оффтоп]
PM WWW   Вверх
borisbn
Дата 28.4.2011, 00:30 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(boostcoder @  27.4.2011,  23:16 Найти цитируемый пост)
не первый год это знаю, но до сих пор не могу запомнить кто из них прямой, а кто обратный 

обратный слеш
я, например, так запомнил: linux - прямой, windows - обратный ( т.е. не прямой, т.е. кривой smile )

а мне понравилось, как в до-диезе сделали unescape:
либо классически
Код

String path = "C:\\path\\to\\file\\name.ext";

либо так
Код

String path = @"C:\path\to\file\name.ext";




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 28.4.2011, 11:30 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Еще одна тема - кандидат на прибивание гвоздями в шапке раздела -
Цитата


Не пытайтесь записать класс в файл через fwrite или write. Ничего хорошего не выйдет.


И еще -
Цитата


В языке С++ string - это полноценный класс, а не просто массив символов.



PM MAIL   Вверх
bsa
Дата 28.4.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



xvr, знаешь, таких тем можно наплодить миллион и маленькую тележку. НО ИХ ВСЕ РАВНО НИКТО ЧИТАТЬ НЕ БУДЕТ. Так как для того, чтобы ее прочитать, нужно сначала самому узнать, в чем дело. А это уже 90% работы. Добавлять в FAQ тоже бесполезно - его все равно никто не читает. Идея с похожими темами могла бы спасти, но, судя по всему, туда тоже никто не заглядывает.
PM   Вверх
xvr
Дата 28.4.2011, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(bsa @  28.4.2011,  11:48 Найти цитируемый пост)
xvr, знаешь, таких тем можно наплодить миллион и маленькую тележку. НО ИХ ВСЕ РАВНО НИКТО ЧИТАТЬ НЕ БУДЕТ

Угу, но я не тему предлагал создать - а повесить это (в раскрытом виде) прямо перед глазами всякого, заходящего в раздел. Остался открытым вопрос - где именно и как это можно повесить  smile 
Так что это скорее вопрос к админам  smile 

PM MAIL   Вверх
catherham
Дата 28.4.2011, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 7.7.2010

Репутация: нет
Всего: нет



Немного разобрался в классе string.
я подключаю билиотеку 
Код

#include <string>

И, если строка не пустая,то стандартный размер 15, в моём случае(возможно зависит от системы, не знаю). Поэтому при записи
Код

table.write(reinterpret_cast<char*>(&znb.cod[k]), sizeof(string));

у меня записывает, только строки длиной до 15 символов.
Но почему если я указываю так
Код

table.write(reinterpret_cast<char*>(&znb.cod[k]), 50);

он всё равно записывает строки до 15 символов корректно, а остальные нет. Ведь по логике при этой записи строка, если она не 50 байт, должна записываться не правильно. Не понимаю, может объяснит кто?
Хочу всё-таки разобраться, и записать не массив символов, а объект класса string

PM MAIL   Вверх
borisbn
Дата 28.4.2011, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(catherham @  28.4.2011,  22:29 Найти цитируемый пост)
Немного разобрался в классе string.

и
Цитата(catherham @  28.4.2011,  22:29 Найти цитируемый пост)
table.write(reinterpret_cast<char*>(&znb.cod[k]), sizeof(string));

Цитата(catherham @  28.4.2011,  22:29 Найти цитируемый пост)
table.write(reinterpret_cast<char*>(&znb.cod[k]), 50);

несовместимо.
Ты вообще читал, что тебе отвечали в теме ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
catherham
Дата 29.4.2011, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 7.7.2010

Репутация: нет
Всего: нет



Но ведь объекты класса можно записывать в файл
PM MAIL   Вверх
RastaDja
Дата 29.4.2011, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 3
Всего: 5



Цитата(catherham @  27.4.2011,  19:17 Найти цитируемый пост)
reinterpret_cast<char*>(&znb.cod[k])


а что мешает сделать znb.cod[k].c_str() ?


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
borisbn
Дата 29.4.2011, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(catherham @  29.4.2011,  10:30 Найти цитируемый пост)
Но ведь объекты класса можно записывать в файл

Вот интересно, почему ты в этом уверен ?

Цитата(RastaDja @  29.4.2011,  10:54 Найти цитируемый пост)
а что мешает сделать znb.cod[k].c_str() ?

а какой задавать размер ? если znb.cod[k].length(), то как потом считывать ?

Добавлено через 3 минуты и 2 секунды
catherham, записать то можно, но прочитать потом корректно - далеко не все. смотри
Код

class MyClass {
public:
    MyClass() {
        ptr = new char[ 100 ];
    }
    ~MyClass() {
        delete [] ptr;
    }
private:
    char * ptr;
};

MyClass obj;

что будет, если ты запишешь obj в файл ? А что будет, если потом считаешь ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1175 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.