Консультация № 184386
05.11.2011, 21:56
100.00 руб.
0 6 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос (ибо нет времени - и так завал полный):

Программка нужна под VS 2008.

Задачка такая (пишу как есть):

С клавиатуры вводятся строки до того момента, пока не введен символ Пробел. Сколько строк -- изначально неизвестно. Нужно их сохранить таким образом, чтобы было char **str и int count, так что в str[0], str[1], ..., str[count - 1] лежали указатели на считанные строки, память отведена с помощью new.

Требуется реализовать так: заводим большой временный буфер (1 кб) для текущей вводимой строки, считываем туда строку с клавиатуры (считаем, что _одна_ строка < 1 кб). Отводим массив длины strlen(...) + 1 и копируем туда введённую строку.
Есть информация, сколько указателей может хранить "внешний" массив. Если он ещё не переполнился, то кладём туда указатель на строчку и увеличиваем count. А иначе сначала заводим массив в два раза большего размера, копируем туда старые указатели, удаляем старый массив, а уже в новый массив кладём указатель. Задача состоит в том, чтобы отвести память "кусочно", сразу целым большим участком.

Спасибо за ответ. Если ответ будет что надо - повышу плату (пусть пока на минимуме будет).

Обсуждение

Неизвестный
06.11.2011, 00:12
общий
06.11.2011, 19:55
это ответ
Здравствуйте, Amfisat!

[code h=207]#include <string.h>

# define blocksize 5; // Задаем константой размер блока

char **strarray = NULL; // Глобальный указатель на массив строк
int count = -1; // Индекс последнего элемента
int size = 0; // Размер массива

void Resize() //Процедура расширения массива
{
char **newarray = NULL;
int newsize = size+blocksize;

newarray = new char*[newsize]; // Выделяем память
if (size!=0)
{
memcpy (newarray,strarray,size*4); // Копируем содержимое старого в новый
delete [] strarray; // Освобождаем память
}
strarray = newarray; // Меняем указатель
size = newsize; // Новый размер массива

}

void AddString (char *string) // Функция добавления строки к массиву
{
int slen = 0;
count++;
if (size==count) Resize(); // Если указатели массива закончились, то увеличиваем размер
slen = strlen(string); // Вычисляем длину строки
strarray[count] = new char[slen+1]; // Выделяем память под строку
strcpy(strarray[count],string); // Копируем строку
}

void Free()
{
for (int i=0; i<=count; i++)
delete [] strarray[i];
delete [] strarray;
count = -1;
size =0;
strarray = NULL;
}
int main(int argc, char* argv[])
{
AddString("Один");
AddString("Два");
AddString("Три");
AddString("Четыре");
AddString("Пять");
AddString("Шесть");
AddString("Семь");

char *t = strarray[3];
t = strarray[6];
t = strarray[2];
Free();

return 0;
}[/code]
5
Неизвестный
06.11.2011, 10:26
общий
А без классов/структур можно сделать, пожалуйста - ничего из этого ещё не проходили ...
Неизвестный
06.11.2011, 12:06
общий
Можно и без классов.

Добавлять строку к массиву функцией AddString.
Удалять массив процедурой Free.

Код:
#include <string.h>

# define blocksize 5; // Задаем константой размер блока

char **strarray = NULL; // Глобальный указатель на массив строк
int count = -1; // Индекс последнего элемента
int size = 0; // Размер массива

void Resize() //Процедура расширения массива
{
char **newarray = NULL;
int newsize = size+blocksize;

newarray = new char*[newsize]; // Выделяем память
if (size!=0)
{
memcpy (newarray,strarray,size*4); // Копируем содержимое старого в новый
delete [] strarray; // Освобождаем память
}
strarray = newarray; // Меняем указатель
size = newsize; // Новый размер массива

}

void AddString (char *string) // Функция добавления строки к массиву
{
int slen = 0;
count++;
if (size==count) Resize(); // Если указатели массива закончились, то увеличиваем размер
slen = strlen(string); // Вычисляем длину строки
strarray[count] = new char[slen+1]; // Выделяем память под строку
strcpy(strarray[count],string); // Копируем строку
}

void Free()
{
for (int i=0; i<=count; i++)
delete [] strarray[i];
delete [] strarray;
count = -1;
size =0;
strarray = NULL;
}
Неизвестный
06.11.2011, 12:47
общий
Круто ...
А можно теперь с функцией main() - показать, как работает программка? - и можно сразу в ответы писать ... Меня устраивает ... Спасибо.
Неизвестный
06.11.2011, 13:07
общий
Простой пример, для консольного приложения.

Код:

int _tmain(int argc, _TCHAR* argv[])
{
AddString("Один");
AddString("Два");
AddString("Три");
AddString("Четыре");
AddString("Пять");
AddString("Шесть");
AddString("Семь");

char *t = strarray[3];
t = strarray[6];
t = strarray[2];
Free();

return 0;
}


P.S. С ответом я малость поторопился. У меня в качестве ответа первый вариант стоит. Теперь не знаю, как отредактировать :)
давно
Посетитель
7438
7205
06.11.2011, 20:00
общий
Да, спешить не стоит. Ответ стоит размещать, когда точно уверен. Все неясности стоит выяснять в мини-форуме. Вот спросили бы Вы о том, с классами делать или нет и не пришлось бы править...

Всегда можно обратиться либо до администратора рассылки, либо до модераторов. Вам помогут.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа