Лекция
Привет, Вы узнаете о том , что такое массивы строк в 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;
}
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;
}
array of c string is fun to use make sure to properly tell the array size
Анализ данных, представленных в статье про массивы строк в c, подтверждает эффективность применения современных технологий для обеспечения инновационного развития и улучшения качества жизни в различных сферах. Надеюсь, что теперь ты понял что такое массивы строк в c и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Структуры данных
Из статьи мы узнали кратко, но содержательно про массивы строк в c
Как мне объявить массив строк? А потом работать с ними. помогите. поскольку я что-то совсем не пойму.. (char )
Ты бы определился, тебе массив статических или динамических строк нужен-то... и сишный или цппшный? И не динамическим ли должен быть сам массив? Определяйся, подскажу.
Я думаю, что так неправильно:
char n m
где n к-ство строк, а m к-ство символов в строке...
Код:
string pStrings=new string n
или:
Код:
char p = Hello , People
Мне нужен для начала статический массив строк (лучше конечно динамический). причем чтобы каждый элемент массива - это строка с динамическим размером. Чтобы было как в CStringArray - только используя чистый сишник.
Ещё одно уточнение - тебе нужен именно массив или список сгодится?
Вариант для массива такой -
Свернуть исходник
Код:
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-ю строку, нужно обойти все начиная с первой.
А вообще повторяюсь еще раз: лучше один раз написать индексированную коллекцию и юзать ее вдоль и поперек :)
char str = new char 10
str = text
Вторая строка приводит к утере памяти, выделенной в первой строке.
Надо писать strcpy (str, text )
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 не будет использоваться, тогда конечно можно выделять строки разной длины.
s = realloc( s, blocksize )
чтобы твоя строка приняла размер blocksize, вот тебе и динамический размер строки, а все остальное сказано уже выше
И как я сам не понял, что реальнее всего можно использовать списки!
Это, во-первых, проще всего.
Во-вторых, работает быстрее )))
Спасибо всем за ответы.
ps. мне кстати идея (но это не чисто его идея, тут подобное уже ранее высказывалось, но все-таки) _north_ очень понравилась! Но я буду использовать все-таки списки )
Если минимальным элементом списка будет один символ, то это не самая хорошая идея
А как тогда лучше?
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
Это С++, а на нем можно было и значительно красивее сделать, если не нравятся стандаотные строки и контейнеры.
А как тогда лучше?
ответ
можно список строк, можно массив строк.
просто когда у тебя каждый символ - элемент списка, у тебя на эти все строки уходит в 9 раз больше памяти, чем нужно.
Единственно, когда может хорошо пройти вариант один символ - один узел , это если тебе надо операции с фрагментами в отдельных строках, ну, там удалить фрагмент, вставить в середину, прицепить к другой строке...
Если поиск сортировка по строкам, удобнее чтобы строка была сплошным блоком
все пишут вот тоже решил не отставать
список строк , выбор контейнера: 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 )
Комментарии
Оставить комментарий
Структуры данных
Термины: Структуры данных