This article contains the source code for a c utility that manages a growing string, and a brief explanation of the code.

To obtain this, we make something similar to a c++ class: a struct with associated functions. The functions add characters to the string in the struct, and allocate more memory space when the string is full.

This is usefull when we are working with string with an unknow length (e.g. we are reading a file).

The struct containing the string is the following:

// Struct containing the growing string
typedef struct
{
	// string
	char * text;
	// string length (with zero terminator)
	int length;
	// string capacity
	int capacity;
} growing_string;

The text variable is where the string is allocated, length is the current string lenght and capacity is the memory allocated for the string.

To better understand the difference between length and capacity, look at the next image:

Capacity-Length

Capacity is the total space allocated for the string, while length is the actual number of character of the string, including the \0 terminator (the special character that close the string). If we add enough characters and the length is greater than the capacity, we need to allocate more memory for the string.


To create the string use the following method:

// Create a new growing string. Return 0 if the operation was done
int new_growing_string(growing_string * str);

This method allocate the memory space for the string in this way:

// alloc string space
str->text = (char *) malloc(sizeof(char) * DEFAULT_INITIAL_SIZE);

DEFAULT_INITIAL_SIZE is a #define with the size that the string will occupy when it’s created. Another #define is DEFAULT_GROW, that indicates the number of characters to add to the string when the capacity is full.

The method that adds characters to the string is the following:

// Add a char to the string. Return 0 if the operation was done
int add_char(growing_string * str, char c);

This method automatically reallocate the memory space for the string when is needed, and adds the character at the end of the string:

int add_char(growing_string * str, char c)
{
	// if the string capacity is reached
	if (str->length >= str->capacity)
	{
		//  increments the string dimension
	}
	// add the character at the end
	str->text[str->length - 1] = (int)c;
	str->text[str->length++] = '\0';
	return 0;
}

If the length is smaller than the capacity, then the character will be added to the end of the string. Otherwise, this code will be executed:

//  increments the string dimension
char * backup = str->text;
int i;
// create the space for the new string
char * tmp = (char *) malloc(sizeof(char) * str->length + DEFAULT_GROW);
if (tmp == NULL)
	return 1;
str->text = tmp;
str->capacity = str->length + DEFAULT_GROW;
// copy the old string
for (i = 0; i length; i++)
{
	str->text[i] = backup[i];
}
// free the memory of the old string
free(backup);

We save the pointer to the old string, assign a larger memory space for the new string, copy the old string into the new space and free the space assigned to the old string.

Other methods of the “class” are:

// frees the space allocated for the string
void delete_growing_string(growing_string * str)
// add to the growing string the string text
int add_string(growing_string * str, char * text)

Following, a code sample that adds to a growing string all ASCII char from 32th to 127th:

int main()
{
	growing_string str;
	new_growing_string(&str);
	for (i = 32; i < 128; i++)
	{
		add_char(&str, (char)i);
	}
	printf("%s", str.text);
	delete_growing_string(&str);
	return (0);
}

In the source code you will find the files growing_string.h, growing_string.c and main.c with an example on how to use the code.

Download Growing String. Downloads: 262


Se sei interessato a questo post, potresti anche provare a leggere:

  • No related posts