I have a function that will parse some data coming in. My problem is that after using strncpy I get some garbage when I try to print it. I try using malloc to make the char
You need to malloc() +1 byte for a string, so it can append the zero when you do strcpy(), but the strncpy will not append zero as well you need a extra byte for it.
Your results are because strncpy
does not put a null character at the end of the string.
One problem: What if there's no newline?
Undefined behaviour:
pos = strchr(temp_str, newline);
strcpy(temp_str, pos+1);
The source and destination of strcpy
must not overlap.
You have to remember in allocating space for a string to add one byte for the terminating '\0' character. You have to be careful with strncpy
, especially if you are used to using strcpy
, strcat
, or sprintf
. Those three functions terminate the string with '\0'. strncpy
copies a number of bytes that you specify, and makes no assumption of terminating the string.
You assume that responsibility by making sure you place a '\0' at the end of the character buffer to which you copied. That means you have to know the starting the position and the length of the copy and put a '\0' one byte past the sum of the starting position and length.
I chose to solve a sample problem slightly differently, but it still involves knowing the length of what I copied.
In this case, I use strncpy
to take the first 9 characters from pcszTestStr1
and
copy them to szTestBuf. Then, I use strcpy -- which terminates the string with a zero --
to append the new part of the sentence.
#include <stdio.h>
#include <string.h>
int n;
int argv_2;
char szTestBuf[100] = {0};
char * pcszTestStr1 =
"This is a very long, long string to be used in a C example, OK?";
int main(int argc, char *argv[])
{
int rc = 0;
printf("The following sentence is too long.\n%s\n", pcszTestStr1);
strncpy(szTestBuf, pcszTestStr1, 9);
strcpy(szTestBuf + 9, " much shorter sentence.");
printf("%s\n", szTestBuf);
return rc;
}
Here's the output of running test.c compiled gcc -o test test.c
.
cnorton@hiawatha:~/scratch$ ./test
The following sentence is too long.
This is a very long, long string to be used in a C example, OK?
This is a much shorter sentence.
cnorton@hiawatha:~/scratch$
Your strncpy(data, pos + 2, (size_t)(pos2-pos));
doesn't add a terminating \0
character at the end of the string. Therefore when you try to print it later, printf()
prints your whole data string and whatever is in the memory right after it, until it reaches zero - that's the garbate you're getting. You need to explicitly append zero at the end of your data. It's also needed for atoi()
.
Edit:
You need to allocate one more byte for your data
, and write a terminating character there. data[len_of_data] = '\0'
. Only after that it becomes a valid C string and you can use it for atoi()
and printf()
.