array of strings in c

Lecture



In programming, it is typical to use an array of strings. For example, a database entry system may check user commands in a string array. To create an array of strings, a two-dimensional array of characters is used. The left index determines the number of lines, and the right index determines the maximum number of characters in each line. This code fragment declares an array of 30 lines, each of which can contain up to 79 characters inclusive:

char str_array [30] [80];

Access to individual rows is very simple - you just need to define the left index. The following statement calls the gets () function, passing it the third line of the str_array array as a parameter:

gets (str_array [2]);

This function is equivalent to

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

but the previous option is more typical when writing professional programs.

To better understand how character arrays work, consider the following program that uses an array as the basis of a simple text editor.



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

/ * text editor * /
int main (void)
{
register int t, i, j;
for (t = 0; t {
printf ("% d:", t);
gets (text [t]);
if (! * text [t]) break; / * exit on an empty line * /
}

/ * character text output * /
for (i = 0; i for (j = 0; text [i] [j]; j ++) printf ("% s", text [i] [j]);
printf ("% s", '\ n');
}
return 0;
}


This program enters text until an empty string is encountered. Then it displays each line. For illustration purposes, it displays the text character by character using the first index. Since each line of the array ends with a null character, the routine that displays the text can be simplified:



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

So, if string C is a one-dimensional character array, then what does an array of string C look like? This is a two-dimensional array of characters!

Here's how to initialize an array of string 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"
};

Since everything except the highest dimension can be omitted in the array declaration, the above declaration can be reduced to:

#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"
};

However, it is recommended to indicate the size of both measurements.

Now each of them arr [x] is a string C, and each arr [x] [y] is a character. This is evidenced by the site https://intellect.icu. You can use any function arr [x] that works with a string!

The following example prints all lines in an array of strings with their lengths.

#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]));
}

The following example flips all rows in an array of strings:

#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

The following example combines all the lines in an array of strings with a space between them into one line:

#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

array of strings in c

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 )


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Structures and data processing algorithms.

Terms: Structures and data processing algorithms.