Страница 1 из 1

Добавить данные в struct (консольное приложение)

Добавлено: 30 окт 2009, 15:57
б_д_в
Доброе время суток!

Код: Выделить всё

struct card 
{
	char *author; 
	char *title;  
	char *city;   
	char *firm;   
	int year;     
	int pages;    
};

struct record 
{
	card book;
	record *prior;
	record *next;
};

card books[] = 
{
		{ "Winer R.S.", "Jasik Turbo C++", "M", "Mir", 1991, 384 },
		{ "Stroustrup B.", "Jasik C++", "Kiev", "DiaSoft", 1993, 560 },
		{ "Turbo C++", "Rukovodstvo programmista", "M", "INTKV", 1991, 394 },
		{ "Lippman S.B.", "C++ dlj nachinauchih", "M", "GELION", 1993, 496 }
};

void main()
{
	record *begin = NULL,  //указатель на начало списка
		   *last = NULL,  // указатель на очередную запись
		   *list;                 //указатель на элементы списка

	//n – кол-во записей в списке
	int n = sizeof(books)/sizeof(books[0]);

	for(int i = 0; i < n; ++i)
	{
		last = new(record);

		(*last).book.author = books[i].author;
		(*last).book.title = books[i].title;
		last->book.city = books[i].city;
		last->book.firm = books[i].firm;
		last->book.year = books[i].year;
		last->book.pages = books[i].pages;

		if(begin == NULL) 
		{
			last->prior = NULL;
			begin = last; 
			last->next = NULL;
		}
		else 
		{ 
			list = begin;

			while(list)
			{
				if(strcmp(last->book.author, list->book.author) < 0)
				{	
					if(begin == list)
					{
						last->prior = NULL;
						begin = last;
					}
					else
					{
						list->prior->next = last;
						last->prior = list->prior;
					}

					list->prior = last;
					last->next = list;

					break;
				}

				if(list->next == NULL)
				{
					last->next = NULL;
					last->prior = list;
					list->next = last;

					break;
				}

				list = list->next;

			} 
		} 
	}

}
Выше написана программа двухсвязного списка который выводит информацию из
books[] = {…} (ф-ции вывода опущены). Все работает. Необходимо в ходе выполнения программы добавить (вручную) какие-то новые данные. Делаю так:

Код: Выделить всё

char *b;
cin >> b;
card str = {b};
books[4] = str;
Программа слетает. Пожалуйста подскажите, сбросьте исходничек или псевдокод, что бы работало. Т.е. к строкам (показанным ниже) добавлялась еще строка. Спасибо.

Winer R.S., Jasik Turbo C++, M, Mir, 1991, 384
Stroustrup B., Jasik C++, Kiev, DiaSoft, 1993, 560
Turbo C++, Rukovodstvo programmista, M, INTKV, 1991, 394
Lippman S.B., C++ dlj nachinauchih, M, GELION, 1993, 496
……………………………………………………
Ххххххххх, хххххххххххх, ххххх, 1111, 222

Re: Добавить данные в struct (консольное приложение)

Добавлено: 30 окт 2009, 16:27
Romeo
1. struct card содержит указатели на начало строки, а не сами строки. Таким образом, если инициализировать массив таких записей статически, то все строки будут размещены в статической памяти и указатели получат существующие адреса из этой памяти.

В случае же, когда статическая инициализация не используется, то выделять память нужно самостоятельно.

Код: Выделить всё

card c;

c.author = new char [30];
cin >> c.author;
// И так для всех полей типа char*

2. Ты не имеешь право писать в элемент books[4], так как массив books имеет 4 элемента.

Re: Добавить данные в struct (консольное приложение)

Добавлено: 30 окт 2009, 18:35
BBB
Romeo писал(а):

Код: Выделить всё

card c;

c.author = new char [30];
cin >> c.author;
// И так для всех полей типа char*

Тут, по идее, по-умному-то, надо как-то отслеживать, чтобы не было "переполнения". Т.е., выделили 30 символов, а если с консоли пользователь введет строку в 30 или более символов?

Re: Добавить данные в struct (консольное приложение)

Добавлено: 31 окт 2009, 10:28
Romeo
Да, само собой, представленный код далёк до совершенства. Это скорее набросок, который показывает как подход решит указанную проблему.

Для того, чтобы всё работало совсем правильно лучше всего вообще перейти на STL строки.

Re: Добавить данные в struct (консольное приложение)

Добавлено: 03 ноя 2009, 22:27
б_д_в
Romeo писал(а): 2. Ты не имеешь право писать в элемент books[4], так как массив books имеет 4 элемента.
Спасибо господа за участие!!!

А как правильно писать в массив books[...].

P.S. Romeo, можно обратиться к тебе по e-mail (как к модератору)? Не нашел твой e-mail.

Re: Добавить данные в struct (консольное приложение)

Добавлено: 04 ноя 2009, 01:59
Romeo
Не нужно по e-mail. Давай обсуждать проблемы здесь, чтобы потомкам что-то оставить.

В массив books не стоит писать, так как он создан статически и очень плохо воспримет перезапись. Лучше воспользуйся STL строками вместо char*, и STL вектором, вместо массива. Использовать вектор более правильно, так как ты собираешь массив расширять в ходе работы программы.

Код: Выделить всё

#include <string>
#include <vector>

struct card 
{
    std::string author; 
    std::string title;  
    std::string city;   
    std::string firm;   
    int year;     
    int pages;    
};

card init_books[] = 
{
        { "Winer R.S.", "Jasik Turbo C++", "M", "Mir", 1991, 384 },
        { "Stroustrup B.", "Jasik C++", "Kiev", "DiaSoft", 1993, 560 },
        { "Turbo C++", "Rukovodstvo programmista", "M", "INTKV", 1991, 394 },
        { "Lippman S.B.", "C++ dlj nachinauchih", "M", "GELION", 1993, 496 }
};

std::vector<card> vecBooks(init_books, init_books+4);

void main()
{
   card newCard;
   // fill new card
   vecBooks.push_back(newCard);
}
Если что, прошу не бить - под рукой нет компилятора. Приду завтра на работу и поправлю, если что.

Re: Добавить данные в struct (консольное приложение)

Добавлено: 04 ноя 2009, 17:15
б_д_в
Romeo писал(а):Не нужно по e-mail. Давай обсуждать проблемы здесь, чтобы потомкам что-то оставить.
Дело в том, что вопрос организационного характера (ты же модератор). К программированию отношения не имеет. Потомкам совсем не будет интересно.

Большое спасибо за исходник, но интересно именно без использования STL (хотя понятно, что это более продвинуто). Так нужно. Если это не очень большая наглость с моей стороны...

Re: Добавить данные в struct (консольное приложение)

Добавлено: 04 ноя 2009, 23:00
Romeo
Если вопрос не касается программирования, то пиши в аську (ищи под моей аватаркой зелёный цветок).

Если STL использовать нельзя, то нужно писать долго и нудно. Как именно нужно поступать, я говорил выше. Программа у тебя не работала лишь потому, что ты не выделял память под строки.

Re: Добавить данные в struct (консольное приложение)

Добавлено: 16 ноя 2009, 14:18
б_д_в
Добавлять нужно наверно так

Код: Выделить всё

cin >> add.author;
…………………..
books[i].author = add.author;
………………………..
Намекни Romeo, в каком месте программы это правильней использовать?
Думаю перед

Код: Выделить всё

(*last).book.author = books[i].author;