C++ Standard Library C-string Functions

C-string is a char array terminated with a null byte(‘\0’), which is the original string that was used since C and early C++.
C/C++ standard library provides useful C-string functions.
The header you need to include to use C-string functions is <cstring>.
In this post, I am going to explain some popular C-string functions with example codes.

Before diving into the examples, it is worthwhile to note that C-string is entirely different from the C++ String class which means you cannot use C string standard library functions with C++ String class.

size_t strlen(const char *str)

Returns the length of the provided char array that doesn’t count the null byte.
size_t is usually a typedef of some larger int such as unsigned.
Although you can directly assign the return value to int you might need to typecast to avoid a compiler warning.

Example Code

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
size_t strlen(const char *str)
{
    size_t len = 0;
    for (; *s; ++len, ++s);
    return len;
}

int main()
{
    char *temp1 = "thishas8";
	cout << strlen(temp1) << endl;
	
	char temp2[] = "thishas8";
	cout << strlen(temp2) << endl;
    return 0;
}

// output
// 8
// 8

int strcmp(const char *str1, const char *str2)

Lexicographically compare s1 and s2 and returns the following result.

  • < 0 if two strings don’t match and the first mismatch char of str1 is less than the one of str2
  • 0 if two string matches
  • > 0 if two strings don’t match and the first mismatch char of str1 is greater than the one of str2

The comparison stops when strings are terminated or unequal characters are found.

Example Code

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
int strcmp(const char *str1, const char *str2)
{
    for (; *str1 && *str2 && *str1 == *str2; ++str1, ++str2);
    if (*str1 == *str2)
    {
        return 0;
    }
    else if (*str1 < *str2)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

int main()
{
    char *temp1 = "this is an example";
    char *temp2 = "this is an example";
    cout << strcmp(temp1, temp2) << endl;
    
    char *temp3 = "this is an example!";
    cout << strcmp(temp1, temp3) << endl;
    
    char *temp4 = "this is an exampl";
    cout << strcmp(temp1, temp4) << endl;
    
    char *temp5 = "this is a different example";
    cout << strcmp(temp1, temp5) << endl;
    return 0;
}

int strncmp(const char *s1, const char *s2, size_t n)

Lexicographically compare s1 and s2 up to ‘n’ characters and returns the following result.

  • < 0 if two strings don’t match and the first mismatch char of str1 is less than the one of str2
  • 0 if two string matches
  • > 0 if two strings don’t match and the first mismatch char of str1 is greater than the one of str2

The comparison stops when strings are terminated or unequal characters are found or have compared ‘n’ characters.

Code Example

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
int strncmp(const char *str1, const char *str2, size_t n)
{
    size_t bytesCompared = 0;
    for (size_t i = 0; 
         i < n && *str1 && *str2 && *str1 == *str2; 
         ++i, ++str1, ++str2, ++bytesCompared);
    
    if (bytesCompared == n || *str1 == *str2)
    {
        return 0;
    }
    else if (*str1 < *str2)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

int main()
{
    char *temp1 = "this is an example";
    char *temp2 = "this is an example";
    cout << strncmp(temp1, temp2, 18) << endl;
    
    char *temp3 = "this is an example!";
    cout << strncmp(temp1, temp3, 18) << endl;
    
    char *temp4 = "this is an exampl";
    cout << strncmp(temp1, temp4, 18) << endl;
    
    char *temp5 = "this is a different example";
    cout << strncmp(temp1, temp5, 18) << endl;
    
    char *temp6 = "this is";
    cout << strncmp(temp1, temp6, 7) << endl;
    return 0;
}

char *strcpy(char *dest, const char *src)

Copies string from src to dest and return dest string pointer.
But you need to make sure there is enough room in dest to prevent any buffer overflow.

Example Code

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
char *strcpy(char *dest, const char *src)
{
    char *iter = dest;
    while (*src)
    {
        *iter++ = *src++;
    }
    
    *iter = '\0';
    return dest;
}

int main()
{
    char *src = "this is an example";
    char dest[19] = {0};
    
    cout << "[" << dest << "]" << endl;
    cout << "[" << strcpy(dest, src) << "]" << endl;
    cout << "[" << dest << "]" << endl;
    cout << "[" << src << "]" << endl;
    return 0;
}

char *strncpy(char *dest, const char *src, size_t n)

Copy exactly ‘n’ characters from src to dest.
If the length of ‘src’ string is less than ‘n’ dest will be padded with 0 until ‘n’ characters are copied.
If the length of ‘src’ string is greater than ‘n’ dest will not have null byte – ‘\0’.
In that case, ‘dest’ string is not null byte terminated which would allow buffer overflow.
Please note that ‘dest’ string needs to have enough space to copy from ‘src’.

Code Example

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
char *strncpy(char *dest, const char *src, size_t n)
{
    char *iter = dest;
    for (size_t i = 0; i < n; ++i, ++iter)
    {
        if (*src)
        {
            *iter = *src++;    
        }
        else
        {
            *iter = '\0';
        }
    }
    
    if (!*src)
    {
        *iter = '\0';    
    }
    
    return dest;
}

int main()
{
    char src[] = "this is an example";
    char dest[sizeof(src)] = {0};
    
    cout << "[" << strncpy(dest, src, sizeof(src)) << "]" << endl;
    cout << "[" << dest << "]" << endl;
    
    char dest2[sizeof(src)] = {0};
    cout << "[" << strncpy(dest2, src, 4) << "]" << endl;
    cout << "[" << dest2 << "]" << endl;
    
    return 0;
}

char *strcat(char *dest, const char *src)

Appends the string ‘src’ to ‘dest’ and returns ‘dest’.
The null byte in ‘dest’ will be overwritten and will be put after src is appended.
Make sure there is enough space in ‘dest’.

Code Example

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
char *strcat(char *dest, const char *src)
{
    char *iter = dest;
    for (; *iter; ++iter);
    
    while (*src)
    {
        *iter++ = *src++;
    }
    
    *iter = '\0';    
    
    return dest;
}

int main()
{
    char dest[100] = {0};
    
    cout << "[" << strcat(dest, "this ") << "]" << endl;
    cout << "[" << strcat(dest, "is ") << "]" << endl;
    cout << "[" << strcat(dest, "an ") << "]" << endl;
    cout << "[" << strcat(dest, "example") << "]" << endl;
    cout << "[" << dest << "]" << endl;
    return 0;
}

char *strncat(char *dest, const char *src, size_t n)

Appends the string ‘src’ to ‘dest’ for first ‘n’ characters and returns ‘dest’.
If ‘src’ is shorter than ‘n’ then only copy ‘src’ until it reaches null byte.
Make sure ‘dest’ has enough space to copy from ‘src’.

Code Example

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
char *strncat(char *dest, const char *src, size_t n)
{
    char *iter = dest;
    for (; *iter; ++iter);
    
    for (size_t i = 0; i < n && *src; ++i)
    {
        *iter++ = *src++; 
    }
    
    *iter = '\0';    
    
    return dest;
}

int main()
{
    char dest[100] = {0};
    
    cout << "[" << strncat(dest, "this ", 6) << "]" << endl;
    cout << "[" << strncat(dest, "is ", 3) << "]" << endl;
    cout << "[" << strncat(dest, "an ", 0) << "]" << endl;
    cout << "[" << strncat(dest, "example", 4) << "]" << endl;
    cout << "[" << dest << "]" << endl;
    return 0;
}

char *strstr(const char *src, const char *sub)

Returns a pointer to the first occurrence of ‘sub’ string in ‘src’.
It will return a null pointer if ‘sub’ is not found in ‘src’.

Code Example

#include <iostream>

using namespace std;

// this is an example implementation of the function
// you just want to import cstring header and use the function there
// as it will be far better and optimized than this one.
char *strstr(const char *src, const char *sub)
{
    char *iter = (char *)src;
    for (; *iter; ++iter)
    {
        char *iterSrc = iter;
        char *iterSub = (char *)sub;
        while (*iterSrc == *iterSub)
        {
            ++iterSrc;
            ++iterSub;
        }
        
        if (!*iterSub)
        {
            return iter;
        }
    }
    
    return 0;
}

// this is for testing purpose
char *strncpy(char *dest, const char *src, size_t n)
{
    char *iter = dest;
    for (size_t i = 0; i < n; ++i, ++iter)
    {
        if (*src)
        {
            *iter = *src++;    
        }
        else
        {
            *iter = '\0';
        }
    }
    
    if (!*src)
    {
        *iter = '\0';    
    }
    
    return dest;
}

int main()
{
    char *src = "This is an example";
    char *sub = "exam";
    
    char *subFound = strstr(src, sub);
    char result[80] = {0}; 
    cout << "[" << strncpy(result, subFound, 4) << "]" << endl;
    cout << "[" << result << "]" << endl;
    
    char *sub2 = "exams";
    subFound = strstr(src, sub2);
    cout << "[" << subFound << "]" << endl;
    
    return 0;
}

Leave a Reply

Your email address will not be published.