Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Массивы строк в C и C++ кратко

Лекция



Привет, Вы узнаете о том , что такое массивы строк в c, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое массивы строк в c , настоятельно рекомендую прочитать все из категории Структуры данных.

В программировании типично использование массив строк. Например, система ввода в базу данных может проверять команды пользователя в строковом массиве. Для создания массива строк используется двумерный массив символов. Левый индекс определяет число строк, а правый индекс - максимальное число символов в каждой строке. Данный фрагмент кода объявляет массив из 30-ти строк, причем каждая может содержать до 79 символов включительно:

char str_array [30] [80];

Доступ к отдельным строкам очень прост - необходимо просто определить левый индекс. Следующий оператор вызывает функцию gets(), передавая ей в качестве параметра третью строку массива str_array:

gets(str_array [2]) ;

Данная функция эквивалентна

gets(&str_array [2] [0]);

но предыдущий вариант более типичен при написании профессиональных программ.

Чтобы лучше понять принцип работы символьных массивов, рассмотрим следующую программу, использующую массив как основу простейшего текстового редактора.



#include
#define MAX 100
#define LEN 255
char text[MAX][LEN];

/* текстовый редактор */
int main(void)
{
register int t, i, j;
for (t=0; t {
printf ("%d: ", t);
gets(text [t]);
if(!*text [t]) break; /* выход по пустой строке */
}

/* посимвольный вывод текста */
for (i=0; i for(j=0; text[i][j]; j++) printf("%с", text[i][j]);
printf ("%с", '\n');
}
return 0;
}


Данная программа осуществляет ввод текста, пока не встретится пустая строка. Затем она отображает каждую строку. В целях иллюстрации она выводит текст посимвольно, с использованием первого индекса. Поскольку каждая строка массива завершается нулевым символом, подпрограмма, отображающая текст, может быть упрощена:



for (i=0; i printf("%s\n", text[i]);

Таким образом, если строка C является одномерным символьным массивом, то как выглядит массив строк C? Это двумерный массив символов!

Вот как можно инициализировать массив строки C:

#define NUMBER_OF_STRING 4
#define MAX_STRING_SIZE 40

char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] =
{ "array of c string",
  "is fun to use",
  "make sure to properly",
  "tell the array size"
};

Поскольку все, кроме самого высокого измерения, могут быть опущены в объявлении массива, приведенное выше объявление может быть уменьшено до:

#define MAX_STRING_SIZE 40

char arr[][MAX_STRING_SIZE] =
{ "array of c string",
  "is fun to use",
  "make sure to properly",
  "tell the array size"
};

Однако рекомендуется указывать размер обоих измерений.

Теперь каждый из них arr[x]представляет собой строку C, а каждый arr[x][y]- символ. Об этом говорит сайт https://intellect.icu . Вы можете использовать любую функцию, arr[x]которая работает со строкой!

Следующий пример печатает все строки в массиве строк с их длинами.

#define NUMBER_OF_STRING 4
#define MAX_STRING_SIZE 40

char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] =
{ "array of c string",
  "is fun to use",
  "make sure to properly",
  "tell the array size"
};

for (int i = 0; i < NUMBER_OF_STRING; i++)
{
    printf("'%s' has length %d\n", arr[i], strlen(arr[i]));
}

Следующий пример переворачивает все строки в массиве строк:

#include

#include

#define NUMBER_OF_STRING 4

#define MAX_STRING_SIZE 40

void print_array(const char arr[NUMBER_OF_STRING][MAX_STRING_SIZE])

{

for (int i = 0; i < NUMBER_OF_STRING; i++)

{

printf("'%s' has length %d\n", arr[i], strlen(arr[i]));

}

}

int main()

{

char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] =

{ "array of c string",

"is fun to use",

"make sure to properly",

"tell the array size"

};

printf("Before reverse:\n");

print_array(arr);

for (int i = 0; i < NUMBER_OF_STRING; i++)

{

for (int j = 0, k = strlen(arr[i]) - 1; j < k; j++, k--)

{

char temp = arr[i][j];

arr[i][j] = arr[i][k];

arr[i][k] = temp;

}

}

printf("\nAfter reverse:\n");

print_array(arr);

return 0;

}

Standard Output

Before reverse:
'array of c string' has length 17
'is fun to use' has length 13
'make sure to properly' has length 21
'tell the array size' has length 19

After reverse:
'gnirts c fo yarra' has length 17
'esu ot nuf si' has length 13
'ylreporp ot erus ekam' has length 21
'ezis yarra eht llet' has length 19

Следующий пример объединяет все строки в массиве строк с пробелом между ними в одну строку:

#include

#include

#define NUMBER_OF_STRING 4

#define MAX_STRING_SIZE 40

#define DEST_SIZE 100

int main()

{

char arr[NUMBER_OF_STRING][MAX_STRING_SIZE] =

{ "array of c string",

"is fun to use",

"make sure to properly",

"tell the array size"

};

char dest[DEST_SIZE] = "";

for (int i = 0; i < NUMBER_OF_STRING; i++)

{

strcat(dest, arr[i]);

if (i < NUMBER_OF_STRING - 1)

{

strcat(dest, " ");

}

}

printf(dest);

return 0;

}

Standard Output

array of c string is fun to use make sure to properly tell the array size

Массивы строк в C и C++

Анализ данных, представленных в статье про массивы строк в c, подтверждает эффективность применения современных технологий для обеспечения инновационного развития и улучшения качества жизни в различных сферах. Надеюсь, что теперь ты понял что такое массивы строк в c и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Структуры данных

Из статьи мы узнали кратко, но содержательно про массивы строк в c
создано: 2019-12-06
обновлено: 2021-03-13
132265



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей


avatar
6.12.2019 9:42

Как мне объявить массив строк? А потом работать с ними. помогите. поскольку я что-то совсем не пойму.. (char )

avatar
6.12.2019 9:42

Ты бы определился, тебе массив статических или динамических строк нужен-то... и сишный или цппшный? И не динамическим ли должен быть сам массив? Определяйся, подскажу.

avatar
6.12.2019 9:43

Я думаю, что так неправильно:

char n m

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

avatar
6.12.2019 9:44

Код:
string pStrings=new string n

или:

Код:
char p = Hello , People

avatar
6.12.2019 9:44

Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.

avatar
6.12.2019 9:44

Ещё одно уточнение - тебе нужен именно массив или список сгодится?
Вариант для массива такой -
Свернуть исходник
Код:
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)
pStrings
pStrings = newStrings
pStrings str_count = new char strlen (str)+1
strcpy (pStrings str_count , str)
str_count++


и т. п.
Такой подход будет ОЧЕНЬ МЕДЛЕННО добавлять и удалять строки, т. к. при каждом добавлении весь массив нужно копировать, при удалении тоже, зато доступ будет произвольный - чтобы получить n-ю строку, нужно просто написать pStrings n .
Если быстродействие при добавлении удалении элементов критично, лучше использовать список. Но тогда будет последовательный доступ - чтобы получить n-ю строку, нужно обойти все начиная с первой.
А вообще повторяюсь еще раз: лучше один раз написать индексированную коллекцию и юзать ее вдоль и поперек :)

avatar
6.12.2019 9:45

char str = new char 10
str = text

Вторая строка приводит к утере памяти, выделенной в первой строке.
Надо писать strcpy (str, text )

avatar
6.12.2019 9:45

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++)
strings
strings
Если операция strcpy не будет использоваться, тогда конечно можно выделять строки разной длины.

avatar
6.12.2019 9:46

s = realloc( s, blocksize )

чтобы твоя строка приняла размер blocksize, вот тебе и динамический размер строки, а все остальное сказано уже выше

avatar
6.12.2019 9:46

И как я сам не понял, что реальнее всего можно использовать списки!
Это, во-первых, проще всего.
Во-вторых, работает быстрее )))

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

ps. мне кстати идея (но это не чисто его идея, тут подобное уже ранее высказывалось, но все-таки) _north_ очень понравилась! Но я буду использовать все-таки списки )

avatar
6.12.2019 9:46

Если минимальным элементом списка будет один символ, то это не самая хорошая идея

avatar
6.12.2019 9:47

А как тогда лучше?

avatar
6.12.2019 9:47

0
спам
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) 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

avatar
6.12.2019 9:47

Это С++, а на нем можно было и значительно красивее сделать, если не нравятся стандаотные строки и контейнеры.

avatar
6.12.2019 9:48

А как тогда лучше?

ответ

можно список строк, можно массив строк.

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

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

Если поиск сортировка по строкам, удобнее чтобы строка была сплошным блоком

avatar
6.12.2019 9:48

все пишут вот тоже решил не отставать
список строк , выбор контейнера: CN = мой контейнер = 0
доб. строку: loadln( строка ) удал. строку по номеру: ln( ном. ) получ. указатель на начало строки: 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 ln(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 )

ln(0)

for (i = 0 i 5 ++i)
if ((tmp = getpln(i)) tmp- s)
puts(tmp- s)
else
puts( no line here )


Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Структуры данных

Термины: Структуры данных