Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.01.2013, 01:08   #41
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Можно поле std::string расположить в конце структуры и читать/писать в файл
в два приема: сначала простые типы общей длиной
sizeof(Programs) - sizeof(std::string)
а потом уже особым способом строку.
EUGY вне форума Ответить с цитированием
Старый 16.01.2013, 01:14   #42
Vlad9999
Пользователь
 
Регистрация: 14.01.2013
Сообщений: 33
По умолчанию

А в этом случае sizeof(std::string) точно вычислит длину строки, или в std::string она всегда одинаковая (максимально-возможная)? В этом случае размер файла будет "раздут". Или я не прав?
Vlad9999 вне форума Ответить с цитированием
Старый 16.01.2013, 01:24   #43
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

sizeof(std::string) - одинаков для любых строк.
Дело в том что ее нутро примитивное.
Условно такое.
Код:
class string
{
private:
char *data;
public:
 char* c_str()
 {
    return data;
 }
};
Фактический размер класса/структуры равен сумме его полей и плюс некоторая поправка на выравнивание по определенным байтовым границам.
Класс строка содержит указатель и длина класса равна длине указателя. (допустим четыре байта).
Когда нужно сохранить строку бессмысленно сохранять адрес этого указателя.
Нужно прочитать всю память по адресу который в этом указателе содержится и закончить чтение по признаку окончания строки \0
EUGY вне форума Ответить с цитированием
Старый 16.01.2013, 01:24   #44
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

sizeof(std::string) - одинаков для любых строк.
Дело в том что ее нутро примитивное.
Условно такое.
Код:
class string
{
private:
char *data;
public:
 char* c_str()
 {
    return data;
 }
};
Фактический размер класса/структуры равен сумме его полей и плюс некоторая поправка на выравнивание по определенным байтовым границам.
Класс строка содержит указатель и длина класса равна длине указателя. (допустим четыре байта).
Когда нужно сохранить строку бессмысленно сохранять адрес этого указателя.
Нужно прочитать всю память по адресу который в этом указателе содержится и закончить чтение по признаку окончания строки \0
EUGY вне форума Ответить с цитированием
Старый 16.01.2013, 19:59   #45
Vlad9999
Пользователь
 
Регистрация: 14.01.2013
Сообщений: 33
По умолчанию

Спасибо большое. Кажется теперь мне все ясно. Получается в плане экономии места на диске std::string будет правильней, чем char[]. Потому что, если я правильно понял, располагаться в файле они будут так: под char[], будет выделено место под каждый символ не зависимо от того будет он туда записан или нет, под std::string - место под указатель на какое-то место в файле и если в строке ничего не записано то на этом месте только признак окончания строки. Если я не прав - поправьте пожалуйста. А как быть,если строчек не одна, а даже несколько массивов строк, в конец писать не получится, или...
Vlad9999 вне форума Ответить с цитированием
Старый 16.01.2013, 20:57   #46
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
Сообщение от Vlad9999 Посмотреть сообщение
и если в строке ничего не записано то на этом месте только признак окончания строки. Если я не прав - поправьте пожалуйста. А как быть,если строчек не одна, а даже несколько массивов строк, в конец писать не получится, или...
Да, вот этот признак окончания и писать в файл.

Цитата:
Сообщение от Vlad9999 Посмотреть сообщение
А как быть,если строчек не одна, а даже несколько массивов строк, в конец писать не получится, или...
Получится. И не обязательно в конце структуры. Просто каждое поле структуры обрабатывать отдельно. Длины всех полей структуры известны.
Длина каждой строки при записи в файл известна. При чтении из файла длина конкретной строки выявляется в цикле.
EUGY вне форума Ответить с цитированием
Старый 16.01.2013, 21:03   #47
Vlad9999
Пользователь
 
Регистрация: 14.01.2013
Сообщений: 33
По умолчанию

Цитата:
Длина каждой строки при записи в файл известна. При чтении из файла длина конкретной строки выявляется в цикле.
Спасибо, теперь по этому вопросу все точки над i расставлены.
Vlad9999 вне форума Ответить с цитированием
Старый 17.01.2013, 00:41   #48
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Код:
При чтении из файла длина конкретной строки выявляется в цикле.
А ещё её длину можно перед самим значением записать. Что мешает перед строкой записать число, а потом считать известное кол-во символов за раз? тем более, что известно когда именно в структуре будет строка.
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 17.01.2013, 02:20   #49
Vlad9999
Пользователь
 
Регистрация: 14.01.2013
Сообщений: 33
По умолчанию

Теоретически думал об этом. Но самостоятельно реализовать пока не в состоянии.
Vlad9999 вне форума Ответить с цитированием
Старый 17.01.2013, 04:10   #50
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
А ещё её длину можно перед самим значением записать.
Почему бы нет, только код короче не станет, а файл будет чуть больше.
Vlad9999, такие задачи пишутся, как слышатся )
Бездумно и линейно
Код:
// структура
struct VERYHARD
{
	int x;
	std::string text1;
	bool y;
	std::string text2;
};


int main()
{

	// путь - имя файла
	const char* myfile = "myfile.dat";

	// создаем десяток элементов структуры 
	const x = 10;
	VERYHARD* vh = new VERYHARD[x];
	
	// заполняем от-балды
	for (int i = x; i--;)
	{ 
		vh[i].x = i;
		vh[i].y = !(i % 2);
		vh[i].text1 = (i % 2) ? "text1" : "text1 qwerty";
		vh[i].text2 = (i % 2) ? "text2 asdfg" : "text2";
	}

	
	// пишем в файл
	if (FILE * stream = fopen(myfile, "w"))
	{
		for (int i = x; i--;)
		{   // пишем каждый элемент отдельно и вдумчиво )
			fwrite( &vh[i].x, sizeof(int), 1, stream ); //  VERYHARD::x
			fwrite( &vh[i].y, sizeof(bool), 1, stream ); // VERYHARD::y
			// запишем сами строки
			fwrite( vh[i].text1.c_str(), sizeof(char), vh[i].text1.length() + 1, stream ); // VERYHARD::text1 + \0
			fwrite( vh[i].text2.c_str(), sizeof(char), vh[i].text2.length() + 1, stream ); // VERYHARD::text2 + \0
		}
		// закрываем файл
		fclose(stream);
	}
	// освобождаем
	delete [] vh;

	// читаем из файла
	if (FILE * stream = fopen(myfile, "r"))
	{
		// читаем до упора
		while(!feof(stream))
		{ 
			VERYHARD scan;
			// читаем x & y
			if (!fread( &scan.x, sizeof(int), 1, stream ))  // VERYHARD::x
				break;
			fread( &scan.y, sizeof(bool), 1, stream ); // VERYHARD::y
			
			char x;
			//VERYHARD::text1
			fread( &x, sizeof(char), 1, stream );
			while (x)
			{
				scan.text1 += x;
				fread( &x, sizeof(char), 1, stream);
			}

			//VERYHARD::text2
			fread( &x, sizeof(char), 1, stream );
			while (x)
			{
				scan.text2 += x;
				fread( &x, sizeof(char), 1, stream);
			}		

			// вывести прочитанную структуру в консоль
			printf("%d, %d, %s, %s\n", scan.x, scan.y, scan.text1.c_str(),  scan.text2.c_str());
		}
		// закрываем файл
		fclose(stream);
	}

	return 0;
}

Последний раз редактировалось EUGY; 17.01.2013 в 08:40.
EUGY вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сортировка в структурах[C++] druger Помощь студентам 0 22.03.2012 19:07
не совсем понял пример в методичке о структурах (С++) severest Общие вопросы C/C++ 1 18.04.2011 20:01
Работа с файлами в структурах ХреновыйПрогер Общие вопросы C/C++ 5 23.12.2010 21:46
Массивы и структуры в структурах (Задача в С++) bel_ka Общие вопросы C/C++ 4 16.12.2007 15:31