Skip to Content
Course content

96: String Concatenation: strcat, strncat

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years back, I was reviewing code for a junior dev who was building a simple file-naming utility. He had a buffer for the filename and was using strcat to append a .log extension to the end of whatever the user provided. It worked perfectly during his initial tests. But the moment a user entered a long filename that pushed the total length right to the edge of the buffer, the program didn't just crash—it started overwriting other variables on the stack. He spent two days chasing a "ghost" bug where a completely unrelated integer variable was changing its value randomly. The culprit? He'd written past the end of his array because strcat doesn't know how big your buffer is; it just keeps writing until it hits the null terminator of the source string.

The Danger of the Blind Append

In C, strcat (string concatenate) is the most straightforward way to glue two strings together. It looks for the null terminator \0 at the end of your destination string and starts copying the source string right there. While it feels intuitive, it's essentially a "blind" operation. The function assumes you've allocated enough memory in the destination buffer to hold both the original string and the new one, plus the final null terminator.

char greeting[20] = "Hello, ";
char name[] = "Christopher";
strcat(greeting, name); 
// greeting now contains "Hello, Christopher"

In the example above, we're safe because 20 bytes is plenty. But if name had been "Christopher-Alexander-the-Great", we would have marched right past the end of the greeting array and into memory we didn't own. This is a classic buffer overflow. I've seen this vulnerability used in countless security exploits; it's why you'll often hear senior devs groan when they see strcat in a pull request.

Capping the Growth with strncat

To avoid the disaster I mentioned, we use strncat. The "n" stands for a limit. This version of the function takes a third argument: the maximum number of characters to append from the source. It's a massive improvement, but there's a subtle trap here that trips up almost everyone at first.

The n parameter is not the total size of the buffer. It is the maximum number of characters to take from the source string. You still have to calculate how much room is actually left in your destination buffer.

char buffer[32] = "Log entry: ";
char message[] = "System failure detected in sector 7G";
int current_len = strlen(buffer);
int space_left = sizeof(buffer) - current_len - 1; // Leave room for \0

strncat(buffer, message, space_left);

Notice that subtraction of 1? That's the most important part of the math. strncat will always append a null terminator after the characters it copies. If you tell it to copy exactly as many characters as there are bytes left in the array, it will write the null terminator one byte past the end of your array. I've spent more hours than I'd like to admit debugging "off-by-one" errors exactly like this. Always leave that one byte of breathing room.




📋 Practical Task

Build a Safe Full-Path Generator

Write a program that constructs a full file path by concatenating a directory string and a filename string. You must ensure that the program never overflows the destination buffer, regardless of how long the input strings are.

  • Define a destination buffer char full_path[100].
  • Initialize it with a directory path, e.g., "/usr/local/bin/".
  • Create a second string for a filename, e.g., "my_custom_script.sh".
  • Use strncat to append the filename to the path.
  • You must calculate the remaining space dynamically using strlen and sizeof to ensure the null terminator is safely placed within the 100-byte limit.
  • Print the final result to the console.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.