Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Массив строк (char*)

249
19 июня 2006 года
DissDoc
639 / / 01.10.2004
Сабж. Как мне объявить массив строк? А потом работать с ними. помогите. поскольку я что-то совсем не соображу...
16K
19 июня 2006 года
LoveLinux
13 / / 15.06.2006
Я думаю, что примерно так:
Цитата:
char [n][m];


где n к-ство строк, а m к-ство символов в строке...

11K
19 июня 2006 года
Ireul
90 / / 15.06.2006
Ты бы определился, тебе массив статических или динамических строк нужен-то... и сишный или цппшный? И не динамическим ли должен быть сам массив? Определяйся, подскажу.
1.8K
19 июня 2006 года
k3Eahn
365 / / 19.12.2005
voi la:
 
Код:
string *pStrings=new string[n];

или:
 
Код:
char *p[]={"Hello","People"};
249
19 июня 2006 года
DissDoc
639 / / 01.10.2004
Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.
350
19 июня 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=DissDoc]Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.[/QUOTE]
Ещё одно уточнение - тебе нужен именно массив или список сгодится?
Вариант для массива такой -
Код:
char **pStrings = 0;  // массив строк (обратите внимание на две звездочки **)
int str_count = 0;    // количество элементов в массиве

void AddString (const char *str)
{
  char **newStrings = new char* [str_count+1];
  memcpy (newStrings, pStrings, sizeof(char*)*str_count);
  delete [] pStrings;
  pStrings = newStrings;
  pStrings[str_count] = new char [strlen (str)+1];
  strcpy (pStrings[str_count], str);
  str_count++;
}

и т. п.
Такой подход будет ОЧЕНЬ МЕДЛЕННО добавлять и удалять строки, т. к. при каждом добавлении весь массив нужно копировать, при удалении тоже, зато доступ будет произвольный - чтобы получить n-ю строку, нужно просто написать pStrings[n].
Если быстродействие при добавлении/удалении элементов критично, лучше использовать список. Но тогда будет последовательный доступ - чтобы получить n-ю строку, нужно обойти все начиная с первой.
А вообще повторяюсь еще раз: лучше один раз написать индексированную коллекцию и юзать ее вдоль и поперек :)
350
19 июня 2006 года
cheburator
589 / / 01.06.2006
[QUOTE=OlgaKr]
 
Код:
char *str = new char[10];
str = "text";
[/QUOTE]
Вторая строка приводит к "утере" памяти, выделенной в первой строке.
Надо писать strcpy (str, "text");
9.4K
19 июня 2006 года
_nоrth_
99 / / 24.04.2006
[QUOTE=DissDoc]Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.[/QUOTE]
Код:
const int SIZE = 3;
  const int MAX_SIZE = 32;

  char **strings = new char* [SIZE];
  for(int i=0; i<SIZE; i++)
    strings = new char[MAX_SIZE];

  strcpy(strings[0], "alfa");
  strcpy(strings[1], "beta");
  strcpy(strings[2], "gamma");

  char *st = new char[sizeof("theta")+1];
  strcpy(st, "theta");
  if(strlen(st)<MAX_SIZE)
    strcpy(strings[0], st);
  else
    throw exception("Длина строки превышает макс.размер");

// ...
// ...
  for(i=0; i<SIZE; i++)
    delete[] strings;
  delete[] strings;
Если операция strcpy не будет использоваться, тогда конечно можно выделять строки разной длины.
13K
19 июня 2006 года
Lucky_Strike
33 / / 04.06.2006
[QUOTE=DissDoc]Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.[/QUOTE]

s = realloc( s, blocksize );

чтобы твоя строка приняла размер blocksize, вот тебе и динамический размер строки, а все остальное сказано уже выше
249
20 июня 2006 года
DissDoc
639 / / 01.10.2004
И как я сам не допер, что реальнее всего можно использовать списки!
Это, во-первых, проще всего.
Во-вторых, работает быстрее )))

Спасибо всем за ответы.

З.Ы. мне кстати идея (но это не чисто его идея, тут подобное уже ранее высказывалось, но все-таки) _north_ очень понравилась! Но я буду использовать все-таки списки )
13K
21 июня 2006 года
Lucky_Strike
33 / / 04.06.2006
Если минимальным элементом списка будет один символ, то это не самая хорошая идея
249
21 июня 2006 года
DissDoc
639 / / 01.10.2004
А как тогда лучше?
1.8K
21 июня 2006 года
k3Eahn
365 / / 19.12.2005
Моя вольная вариация на тему массива(add - добавить строку, init - иницализация массива, remove - удалить элемент, get - возвращает указатель на строку в массиве):
Код:
typedef struct {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
UINT iPrevFree;
bool bAlloc;
bool bFree;
} ANSI_STRING, *PANSI_STRING;
 
typedef struct
{
int iNum;
int iFree;
ANSI_STRING as[1];
}STRINGARRAY,*PSTRINGARRAY;
 
PSTRINGARRAY init(int);
UINT add(PSTRINGARRAY,char*);
void remove(PSTRINGARRAY,UINT);
char * get(PSTRINGARRAY,UINT);
 
PSTRINGARRAY init(int iNum)
{
PSTRINGARRAY p=(PSTRINGARRAY)new char[iNum*sizeof(ANSI_STRING)+sizeof(int)*2];
memset(p,0,iNum*sizeof(ANSI_STRING)+sizeof(int)*2);
p->iNum=iNum;
 
for(UINT u=0;u<iNum;u++)
p->as.iPrevFree=u+1;
return p;
};
 
UINT add(PSTRINGARRAY p,char *psz)
{
UINT iFree=p->iFree;
 
if(iFree>=p->iNum)
return (UINT)-1;
PANSI_STRING pasFree=&p->as[iFree];
int iLen=strlen(psz);
 
if(pasFree->MaximumLength<iLen)
{
if(pasFree->bAlloc) delete [] pasFree->Buffer;
pasFree->Buffer=new char[iLen+1];
pasFree->MaximumLength=iLen;
pasFree->bAlloc=TRUE;
};
 
pasFree->bFree=FALSE;
strcpy(pasFree->Buffer,psz);
pasFree->Length=iLen;
p->iFree=pasFree->iPrevFree;
return iFree;
};
 
void remove(PSTRINGARRAY p,UINT i)
{
if(i>=p->iNum || i==p->iFree)
return;
PANSI_STRING pas=&p->as;
 
if(pas->bFree)
return;
pas->bFree=TRUE;
pas->iPrevFree=p->iFree;
p->iFree=i;
}
 
char * get(PSTRINGARRAY p,UINT i)
{
if(i>=p->iNum || i==p->iFree)
return NULL;
PANSI_STRING pas=&p->as;
 
if(pas->bFree)
return NULL;
return pas->Buffer;
};
3
21 июня 2006 года
Green
4.8K / / 20.01.2000
Но ведь это же не С.
Это С++, а на нем можно было и значительно красивее сделать, если не нравятся стандаотные строки и контейнеры.
13K
22 июня 2006 года
Lucky_Strike
33 / / 04.06.2006
[QUOTE=DissDoc]А как тогда лучше?[/QUOTE]
можно список строк, можно массив строк.

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

Единственно, когда может хорошо пройти вариант "один символ - один узел", это если тебе надо операции с фрагментами в отдельных строках, ну, там удалить фрагмент, вставить в середину, прицепить к другой строке...

Если поиск/сортировка по строкам, удобнее чтобы строка была сплошным блоком
13K
22 июня 2006 года
Lucky_Strike
33 / / 04.06.2006
все пишут вот тоже решил не отставать
"список строк", выбор контейнера: CN = <мой контейнер> = 0;
доб. строку: loadln( <строка> ); удал. строку по номеру: deleteln(<ном.>); получ. указатель на начало строки: getpln( <номер> );
вроде пашет
Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct line{
   struct line *up, *dn;
   char * s;
} line;

line *CN;

void loadln(char *s)
{
    line *tmp, *A = calloc(1, sizeof(line));
    int l = strlen(s);
    A->s = malloc(l);
    strcpy(A->s, s, l);
   
    if (!CN)
        { CN = A; return; }
   
    tmp = CN;
    while (tmp->dn)
        tmp = tmp->dn;

    tmp->dn = A;
    tmp->dn->dn = 0;
    tmp->dn->up = tmp;
}

line* getpln(int n)
{
    int i;
    line *tmp = CN;
    for (i = 0; i < n; ++i)
        if (tmp->dn)
            tmp = tmp->dn;
        else
            return 0;
    return tmp;
}

int deleteln(int n)
{
    line *tmp = getpln(n);
    if (tmp) {
        if (! tmp->up)
            CN = tmp->dn;  
        else
            tmp->up->dn  =  tmp->dn;
        if (tmp->dn) tmp->dn->up  = tmp->up;
        free(tmp);
        return n;
    }  
    else
        return 0;
}

main()
{  
    line *tmp,  *my_lines = CN = 0;
    int i;
    char s;

    loadln( "Hello World" );
    loadln( "Microsoft .NET Framework, "  );
    loadln( "COBOL"  );
   
    deleteln(0);

    for (i = 0; i < 5; ++i)
        if ((tmp = getpln(i)) && tmp->s)
            puts(tmp->s);
        else
            puts("<no line here>");
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог