Segmentation fault with strcpy, even though pointers have pointee - c

void trim(char *line)
{
int i = 0;
char new_line[strlen(line)];
char *start_line = line;
while (*line != '\0')
{
if (*line != ' ' && *line != '\t')
{
new_line[i] = *line;
i++;
}
line++;
}
new_line[i] = '\0';
printf("%s\n", start_line);
printf("%s\n", new_line);
strcpy(start_line, new_line);
}
I really cannot find the problem here. My pointers are initialized, and I made a pointer to have the start of the string line. At the end I would like to copy the new line in the old one, so the caller has a changed value of his line.
But strcpy() makes a segmentation fault. What is wrong?
This is the code that calls trim():
char *str = "Irish People Try American Food";
printf("%s\n", str);
trim(str);
printf("%s\n", str);

You need to show the whole program; what calls "trim()"? Paul R's answer is right, you are one character short and it should be at least:
char new_line[strlen(line) + 1];
However, this will not always cause a segfault, and if it did it would probably not be at strcpy().
The likely reason strcpy(start_line, new_line) is faulting is that start_line points to the original value of line. It is likely that you are calling the function like:
int main() {
trim("blah blah\tblah");
return 0;
}
If so, line is a pointer to a constant char array that can't be modified. On many OS's this is stored in a read-only memory area, so it will cause an immediate segmentation fault if a write attempt is made. So strcpy() then faults when trying to write into to this read only location.
As a quick test try this:
int main() {
char test[100] = "blah blah\tblah";
trim(test);
return 0;
}
If it works, that's your specific issue with strcpy() faulting.
EDIT - the question was updated later to include the main() calling function, which confirmed that the trim function was called with a pointer to a string constant. The problem line is:
char *str = "Irish People Try American Food";
This creates a string literal, an array of 31 characters including a null terminator which cannot be modified. The pointer str is then initialized with the address of this constant, array.
The correction is to allocate a regular array of characters and then initialize it with the known string. In this case the assignment and temporary constant string literal may or may not be optimized out, but the end result is always the same - a writable array of characters initialized with the desired text:
char str[100] = "Irish People Try American Food";
/* or */
char str2[] = "American People Like Irish Beer";
/* or */
char *str3[37];
strcpy(str3, "And German Beer"); /* example only, need to check length */
These create normal writable char arrays of lengths 100, 32, and 37, respectively. Each is then initialized with the given strings.
The ANSI/ISO C standard defined the language such that a string literal is a array of char that cannot be modified. This is the case even as it was first standardized in C89. Prior to this string literals had been commonly writable, such as in the pre-standard K&R C of very early UNIX code.
Identical string literals of either form need not be distinct. If
the program attempts to modify a string literal of either form, the
behavior is undefined. - ANSI X3.159-1989
Many C89 and newer compilers have since then placed this array into the .text or .rodata segments where it may even be physically unwritable (ROM, read-only MMU pages, etc.), as discovered here. Compilers may also coalesce duplicate string constants into single one to conserve space - and you wouldn't to write into "one" of those either!
The fact that these semantically unwritable strings were still left as type char *, and that they could be assigned to and passed as such was known to be a compromise, even as the C89 standard was being drafted. That they did not use the then-brand-new type qualifier const was described as a "not-completely-happy result". See Richie's (DMR's) explanation.
And apparently that result still boomerangs around and whacks people upside the head nearly 30 years later.

Your new_line string is one char too small - it does not have room for the final '\0' terminator - change:
char new_line[strlen(line)];
to:
char new_line[strlen(line) + 1];
You should also be aware that string literals can not be modified, so if you try to call your function like this:
trim("Hello world!");
then this will result in undefined behaviour. (You should also get a compiler warning if you try to do this.)

As #PaulR stated, your new line's buffer is too small. But instead of using another buffer that takes up more space, you could use a single-character approach, like this:
void trim(char *s)
{
char *src = s, *dest = s;
while (*src)
{
if ((*src != ' ') && (*src != '\t'))
*dest++ = *src;
++src;
}
*dest = '\0';
}

Related

Usage of pointers as parameters in the strcpy function. Trying to understand code from book

From my book:
void strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
I'm trying to understand this snippet of code from my textbook. They give no main function so I'm trying to wrap my head around how the parameters would be used in a call to the function. As I understand it, the "i-number" of characters of string t[ ] are being copied to the string s[ ] until there are no longer characters to read, from the \0 escape sequence. I don't really understand how the parameters would be defined outside of the function. Any help is greatly appreciated. Thank you.
Two things to remember here:
Strings in C are arrays of chars
Arrays are passed to functions as pointers
So you would call this like so:
char destination[16];
char source[] = "Hello world!";
strcpy(destination, source);
printf("%s", destination);
i is just an internal variable, it has no meaning outside the strcpy function (it's not a parameter or anything). This function copies the entire string t to s, and stops when it sees a \0 character (which marks the end of a string by C convention).
EDIT: Also, strcpy is a standard library function, so weird things might happen if you try to redefine it. Give your copy a new name and all will be well.
Here's a main for you:
int main()
{
char buf[30];
strcpy(buf, "Hi!");
puts(buf);
strcpy(buf, "Hello there.");
puts(buf);
}
The point of s and t are to accept character arrays that exist elsewhere in the program. They are defined elsewhere, at this level usually by the immediate caller or one more caller above. Their meanings are replaced at runtime.
Your get compile problems because your book is wrong. Should read
const strcpy (char *s, const char *t)
{
...
return s;
}
Where const means will not modify. Because strcpy is a standard function you really do need it to be correct.
Here is how you might use the function (note you should change the function name as it will conflict with the standard library)
void my_strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
int main()
{
char *dataToCopy = "This is the data to copy";
char buffer[81]; // This buffer should be at least big enough to hold the data from the
// source string (dataToCopy) plus 1 for the null terminator
// call your strcpy function
my_strcpy(buffer, dataToCopy);
printf("%s", buffer);
}
In the code, the i variable is pointing to the character in the character array. So when i is 0 you are pointing to the first character of s and t. s[i] = t[i]copies the i'th character from t to the i'th character of s. This assignment in C is self an expression and returns the character that was copied, which allows you to compare that to the null terminator 0 ie. (s[i] = t[i]) != ’\0’ which indicates the end of the string, if the copied character is not a null terminator the loop continues otherwise it will end.

C String parsing errors with strtok(),strcasecmp()

So I'm new to C and the whole string manipulation thing, but I can't seem to get strtok() to work. It seems everywhere everyone has the same template for strtok being:
char* tok = strtok(source,delim);
do
{
{code}
tok=strtok(NULL,delim);
}while(tok!=NULL);
So I try to do this with the delimiter being the space key, and it seems that strtok() no only reads NULL after the first run (the first entry into the while/do-while) no matter how big the string, but it also seems to wreck the source, turning the source string into the same thing as tok.
Here is a snippet of my code:
char* str;
scanf("%ms",&str);
char* copy = malloc(sizeof(str));
strcpy(copy,str);
char* tok = strtok(copy," ");
if(strcasecmp(tok,"insert"))
{
printf(str);
printf(copy);
printf(tok);
}
Then, here is some output for the input "insert a b c d e f g"
aaabbbcccdddeeefffggg
"Insert" seems to disappear completely, which I think is the fault of strcasecmp(). Also, I would like to note that I realize strcasecmp() seems to all-lower-case my source string, and I do not mind. Anyhoo, input "insert insert insert" yields absolutely nothing in output. It's as if those functions just eat up the word "insert" no matter how many times it is present. I may* end up just using some of the C functions that read the string char by char but I would like to avoid this if possible. Thanks a million guys, i appreciate the help.
With the second snippet of code you have five problems: The first is that your format for the scanf function is non-standard, what's the 'm' supposed to do? (See e.g. here for a good reference of the standard function.)
The second problem is that you use the address-of operator on a pointer, which means that you pass a pointer to a pointer to a char (e.g. char**) to the scanf function. As you know, the scanf function want its arguments as pointers, but since strings (either in pointer to character form, or array form) already are pointer you don't have to use the address-of operator for string arguments.
The third problem, once you fix the previous problem, is that the pointer str is uninitialized. You have to remember that uninitialized local variables are truly uninitialized, and their values are indeterminate. In reality, it means that their values will be seemingly random. So str will point to some "random" memory.
The fourth problem is with the malloc call, where you use the sizeof operator on a pointer. This will return the size of the pointer and not what it points to.
The fifth problem, is that when you do strtok on the pointer copy the contents of the memory pointed to by copy is uninitialized. You allocate memory for it (typically 4 or 8 bytes depending on you're on a 32 or 64 bit platform, see the fourth problem) but you never initialize it.
So, five problems in only four lines of code. That's pretty good! ;)
It looks like you're trying to print space delimited tokens following the word "insert" 3 times. Does this do what you want?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char str[BUFSIZ] = {0};
char *copy;
char *tok;
int i;
// safely read a string and chop off any trailing newline
if(fgets(str, sizeof(str), stdin)) {
int n = strlen(str);
if(n && str[n-1] == '\n')
str[n-1] = '\0';
}
// copy the string so we can trash it with strtok
copy = strdup(str);
// look for the first space-delimited token
tok = strtok(copy, " ");
// check that we found a token and that it is equal to "insert"
if(tok && strcasecmp(tok, "insert") == 0) {
// iterate over all remaining space-delimited tokens
while((tok = strtok(NULL, " "))) {
// print the token 3 times
for(i = 0; i < 3; i++) {
fputs(tok, stdout);
}
}
putchar('\n');
}
free(copy);
return 0;
}

Simple C syntax for subtracting from char type, lowercase

I'm getting a seg. fault when I try to subtract 32 from a char type (trying to convert to lowercase without tolower() in C. I have done the prerequisite searching for relevant Q/A threads with no luck. I also tried 'a' - 'A' for the conversion value, '32', casting it as (char*) and anything else I could think of. For an example:
char* s1 = "Bob";
if (*s1 >= 97 && *s1 <= 122)
*s1 -= 32;
}
Any advice?
Edit:
After following the help below, I still get the error. (For this example, I am only trying to change the first letter of the name to lowercase.) Here is what I am trying:
char* s1 = "Bob";
printf("\n %s before", s1);
// below I call my string length function to get actual size instead of 100
char* temp = malloc(100);
temp = s1;
if (*temp >= 'A' && *temp <= 'Z'){
*temp -= 32;
}
printf("\n%s after", temp);
free(temp);
Also, why do I need to allocate memory for a string that already is in memory?
You can't alter literal strings like that - they are (usually) in read-only memory. You need to make a writeable copy of the string literal:
char* name = "Bob";
char* s1 = strdup(name);
...
free(s1); // And you also need this to avoid a memory leak!
There are a number of problems with your code.
char* s1 = "Bob";
A string literal creates a read-only array of char; this array is static meaning that it exists for the entire lifetime of your program. For historical reasons, it's not const, so the compiler won't necessarily warn you if you attempt to modify it, but you should carefully avoid doing so.
s1 points to the first character of that array. You may not modify *s1. For safety, you should declare the pointer as const:
const char *s1 = "Bob";
If you want a modifiable character array, you can create it like this:
char s1[] = "Bob";
Now let's look at the remaining code:
if (*s1 >= 97 && *s1 <= 122)
*s1 -= 32;
}
97 and 122 are the numeric ASCII codes for 'a' and 'z'. 32 is the difference between a lower case letter and the corresponding upper case letter -- again, in ASCII.
The C language doesn't guarantee that characters are represented in ASCII, or in any of the character sets that are compatible with it. On an IBM mainframe, for example, characters are represented in EBCDIC, in which the codes for the letters are not contiguous (there are gaps), and the difference between corresponding lower case and upper case letters is 64, not 32.
EBCDIC systems are rare these days, but even so, portable code tends to be clearer than non-portable code, even aside from any practical issues of whether the code will work on all systems.
As I'm sure you know, the best way to do this is to use the tolower function:
*s1 = tolower((unsigned char)*s1);
Note the cast to unsigned char. The to*() and is*() functions declared in <ctype.h> are oddly behaved, for historical reasons. They don't work on char arguments; rather, they work on int arguments that are within the range of unsigned char. (They also accept EOF, which is typically -1). If plain char is signed, then passing a char value that happens to be negative causes undefined behavior. Yes, it's annoying.
But you say you don't want to use tolower. (Which is fine; learning to do things like this yourself is a good exercise.)
If you're willing to assume that upper case letters are contiguous, and that lower case letters are contiguous, then you can do something like this:
if (*s1 >= 'a' && *s1 <= 'z') {
*s1 -= 'a' - 'A';
}
That's still not portable to non-ASCII systems, but it's a lot easier to read if you don't happen to have the ASCII table memorized.
It also makes it a little more obvious that you've got the logic backwards. You say you want to convert to lower case, but your code converts from lower case to upper case.
Or you can use a lookup table that maps lower case letters to upper case letters:
char to_lower[CHAR_MAX] = { 0 }; /* sets all elements to 0 */
to_lower['A'] = 'a';
to_lower['B'] = 'b';
/* ... */
to_lower['Z'] = 'z';
Or, if your compiler supports compound literals:
const char to_lower[CHAR_MAX] = {
['A'] = 'a',
['B'] = 'b',
/* ... */
};
I'll leave it to you to fill in the rest write the code to use it.
And now you can see why the tolower and toupper functions exist -- so you don't have to deal with all this stuff (apart from the odd unsigned char casts you'll need).
UPDATE :
In response to the new parts of your question:
char* temp = malloc(100);
temp = s1;
That assignment temp = s1; doesn't copy the allocated string; it just copies the pointer. temp points to 100 bytes of allocated space, but then you make temp point to the (read-only) string literal, and you've lost any references to the allocated space, creating a memory leak.
You can't assign strings or arrays in C. To copy a string, use the strcpy() function:
char *temp = malloc(100);
if (temp == NULL) { /* Don't assume the allocation was successful! */
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(temp, s1);
Also, why do I need to allocate memory for a string that already is in memory?
It's in memory, but it's memory that you're not allowed to modify. If you want to modify it, you need to copy it to a modifiable location. Or, as I suggested above, you can put it in read/write memory in the first place:
char s[] = "Bob";
That initialization copies the string into the array s.
Initialize char and use malloc to allocat memory to store all string and than use for loop and convert whole string in lower case.
You need to
Allocate buffer
Copy string "Bob" to your buffer
Loop through the string, editing it as you go.
This fails because string literals are usually stored in read-only memory.
The easiest fix is to use the literal to initialize an array, the array will be modifiable (unless explicitly made const so don't do that):
char s1[] = "Bob";
Also, it's very bad form to hardcode ASCII, use the islower() and tolower() functions from <ctype.h> to make this code proper.
char *s1 = "Bob";
is creating a pointer to a string constant. That means the string "Bob" will be somewhere in the read-only part of the memory and you just have a pointer to it. You can use the string as read-only. You cannot make changes to it.
Example:
s1[0] = 'b';
Is asking for trouble.
To make changes to s1 you should allocate memory for it
s1 = malloc(10); //or what you want
Now changes to s1 can be done easily.

Implementing a string copy function in C

At a recent job interview, I was asked to implement my own string copy function. I managed to write code that I believe works to an extent. However, when I returned home to try the problem again, I realized that it was a lot more complex than I had thought. Here is the code I came up with:
#include <stdio.h>
#include <stdlib.h>
char * mycpy(char * d, char * s);
int main() {
int i;
char buffer[1];
mycpy(buffer, "hello world\n");
printf("%s", buffer);
return 0;
}
char * mycpy (char * destination, char * source) {
if (!destination || !source) return NULL;
char * tmp = destination;
while (*destination != NULL || *source != NULL) {
*destination = *source;
destination++;
source++;
}
return tmp;
}
I looked at some other examples online and found that since all strings in C are null-terminated, I should have read up to the null character and then appended a null character to the destination string before exiting.
However one thing I'm curious about is how memory is being handled. I noticed if I used the strcpy() library function, I could copy a string of 10 characters into a char array of size 1. How is this possible? Is the strcpy() function somehow allocating more memory to the destination?
Good interview question has several layers, to which to candidate can demonstrate different levels of understanding.
On the syntactic 'C language' layer, the following code is from the classic Kernighan and Ritchie book ('The C programming language'):
while( *dest++ = *src++ )
;
In an interview, you could indeed point out the function isn't safe, most notably the buffer on *dest isn't large enough. Also, there may be overlap, i.e. if dest points to the middle of the src buffer, you'll have endless loop (which will eventually creates memory access fault).
As the other answers have said, you're overwriting the buffer, so for the sake of your test change it to:
char buffer[ 12 ];
For the job interview they were perhaps hoping for:
char *mycpy( char *s, char *t )
{
while ( *s++ = *t++ )
{
;
}
return s;
}
No, it's that strcpy() isn't safe and is overwriting the memory after it, I think. You're supposed to use strncpy() instead.
No, you're writing past the buffer and overwriting (in this case) the rest of your stack past buffer. This is very dangerous behavior.
In general, you should always create methods that supply limits. In most C libraries, these methods are denoted by an n in the method name.
C does not do any run time bounds checking like other languages(C#,Java etc). That is why you can write things past the end of the array. However, you won't be able to access that string in some cases because you might be encroaching upon memory that doesn't belong to you giving you a segementation fault. K&R would be a good book to learn such concepts.
The strcpy() function forgoes memory management entirely, therefore all allocation needs to be done before the function is called, and freed afterward when necessary. If your source string has more characters than the destination buffer, strcpy() will just keep writing past the end of the buffer into unallocated space, or into space that's allocated for something else.
This can be very bad.
strncpy() works similarly to strcpy(), except that it allows you to pass an additional variable describing the size of the buffer, so the function will stop copying when it reaches this limit. This is safer, but still relies on the calling program to allocate and describe the buffer properly -- it can still go past the end of the buffer if you provide the wrong length, leading to the same problems.
char * mycpy (char * destination, char * source) {
if (!destination || !source) return NULL;
char * tmp = destination;
while (*destination != NULL || *source != NULL) {
*destination = *source;
destination++;
source++;
}
return tmp;
}
In the above copy implementation, your tmp and destination are having the same data. Its better your dont retrun any data, and instead let the destination be your out parameter. Can you rewrite the same.
The version below works for me. I'm not sure if it is bad design though:
while(source[i] != '\0' && (i<= (MAXLINE-1)))
{
dest[i]=source[i];
++i;
}
In general it's always a good idea to have const modifier where it's possible, for example for the source parameter.

Copying a part of a string (substring) in C

I have a string:
char * someString;
If I want the first five letters of this string and want to set it to otherString, how would I do it?
#include <string.h>
...
char otherString[6]; // note 6, not 5, there's one there for the null terminator
...
strncpy(otherString, someString, 5);
otherString[5] = '\0'; // place the null terminator
Generalized:
char* subString (const char* input, int offset, int len, char* dest)
{
int input_len = strlen (input);
if (offset + len > input_len)
{
return NULL;
}
strncpy (dest, input + offset, len);
return dest;
}
char dest[80];
const char* source = "hello world";
if (subString (source, 0, 5, dest))
{
printf ("%s\n", dest);
}
char* someString = "abcdedgh";
char* otherString = 0;
otherString = (char*)malloc(5+1);
memcpy(otherString,someString,5);
otherString[5] = 0;
UPDATE:
Tip: A good way to understand definitions is called the right-left rule (some links at the end):
Start reading from identifier and say aloud => "someString is..."
Now go to right of someString (statement has ended with a semicolon, nothing to say).
Now go left of identifier (* is encountered) => so say "...a pointer to...".
Now go to left of "*" (the keyword char is found) => say "..char".
Done!
So char* someString; => "someString is a pointer to char".
Since a pointer simply points to a certain memory address, it can also be used as the "starting point" for an "array" of characters.
That works with anything .. give it a go:
char* s[2]; //=> s is an array of two pointers to char
char** someThing; //=> someThing is a pointer to a pointer to char.
//Note: We look in the brackets first, and then move outward
char (* s)[2]; //=> s is a pointer to an array of two char
Some links:
How to interpret complex C/C++ declarations and
How To Read C Declarations
You'll need to allocate memory for the new string otherString. In general for a substring of length n, something like this may work for you (don't forget to do bounds checking...)
char *subString(char *someString, int n)
{
char *new = malloc(sizeof(char)*n+1);
strncpy(new, someString, n);
new[n] = '\0';
return new;
}
This will return a substring of the first n characters of someString. Make sure you free the memory when you are done with it using free().
You can use snprintf to get a substring of a char array with precision:
#include <stdio.h>
int main()
{
const char source[] = "This is a string array";
char dest[17];
// get first 16 characters using precision
snprintf(dest, sizeof(dest), "%.16s", source);
// print substring
puts(dest);
} // end main
Output:
This is a string
Note:
For further information see printf man page.
You can treat C strings like pointers. So when you declare:
char str[10];
str can be used as a pointer. So if you want to copy just a portion of the string you can use:
char str1[24] = "This is a simple string.";
char str2[6];
strncpy(str1 + 10, str2,6);
This will copy 6 characters from the str1 array into str2 starting at the 11th element.
I had not seen this post until now, the present collection of answers form an orgy of bad advise and compiler errors, only a few recommending memcpy are correct. Basically the answer to the question is:
someString = allocated_memory; // statically or dynamically
memcpy(someString, otherString, 5);
someString[5] = '\0';
This assuming that we know that otherString is at least 5 characters long, then this is the correct answer, period. memcpy is faster and safer than strncpy and there is no confusion about whether memcpy null terminates the string or not - it doesn't, so we definitely have to append the null termination manually.
The main problem here is that strncpy is a very dangerous function that should not be used for any purpose. The function was never intended to be used for null terminated strings and it's presence in the C standard is a mistake. See Is strcpy dangerous and what should be used instead?, I will quote some relevant parts from that post for convenience:
Somewhere at the time when Microsoft flagged strcpy as obsolete and dangerous, some other misguided rumour started. This nasty rumour said that strncpy should be used as a safer version of strcpy. Since it takes the size as parameter and it's already part of the C standard lib, so it's portable. This seemed very convenient - spread the word, forget about non-standard strcpy_s, lets use strncpy! No, this is not a good idea...
Looking at the history of strncpy, it goes back to the very earliest days of Unix, where several string formats co-existed. Something called "fixed width strings" existed - they were not null terminated but came with a fixed size stored together with the string. One of the things Dennis Ritchie (the inventor of the C language) wished to avoid when creating C, was to store the size together with arrays [The Development of the C Language, Dennis M. Ritchie]. Likely in the same spirit as this, the "fixed width strings" were getting phased out over time, in favour for null terminated ones.
The function used to copy these old fixed width strings was named strncpy. This is the sole purpose that it was created for. It has no relation to strcpy. In particular it was never intended to be some more secure version - computer program security wasn't even invented when these functions were made.
Somehow strncpy still made it into the first C standard in 1989. A whole lot of highly questionable functions did - the reason was always backwards compatibility. We can also read the story about strncpy in the C99 rationale 7.21.2.4:
The strncpy function
strncpy was initially introduced into the C library to deal with fixed-length name fields in
structures such as directory entries. Such fields are not used in the same way as strings: the
trailing null is unnecessary for a maximum-length field, and setting trailing bytes for shorter
5 names to null assures efficient field-wise comparisons. strncpy is not by origin a “bounded
strcpy,” and the Committee preferred to recognize existing practice rather than alter the function
to better suit it to such use.
The Codidact link also contains some examples showing how strncpy will fail to terminate a copied string.
I think it's easy way... but I don't know how I can pass the result variable directly then I create a local char array as temp and return it.
char* substr(char *buff, uint8_t start,uint8_t len, char* substr)
{
strncpy(substr, buff+start, len);
substr[len] = 0;
return substr;
}
strncpy(otherString, someString, 5);
Don't forget to allocate memory for otherString.
#include <stdio.h>
#include <string.h>
int main ()
{
char someString[]="abcdedgh";
char otherString[]="00000";
memcpy (otherString, someString, 5);
printf ("someString: %s\notherString: %s\n", someString, otherString);
return 0;
}
You will not need stdio.h if you don't use the printf statement and putting constants in all but the smallest programs is bad form and should be avoided.
Doing it all in two fell swoops:
char *otherString = strncpy((char*)malloc(6), someString);
otherString[5] = 0;
char largeSrt[] = "123456789-123"; // original string
char * substr;
substr = strchr(largeSrt, '-'); // we save the new string "-123"
int substringLength = strlen(largeSrt) - strlen(substr); // 13-4=9 (bigger string size) - (new string size)
char *newStr = malloc(sizeof(char) * substringLength + 1);// keep memory free to new string
strncpy(newStr, largeSrt, substringLength); // copy only 9 characters
newStr[substringLength] = '\0'; // close the new string with final character
printf("newStr=%s\n", newStr);
free(newStr); // you free the memory
Try this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* substr(const char *src, unsigned int start, unsigned int end);
int main(void)
{
char *text = "The test string is here";
char *subtext = substr(text,9,14);
printf("The original string is: %s\n",text);
printf("Substring is: %s",subtext);
return 0;
}
char* substr(const char *src, unsigned int start, unsigned int end)
{
unsigned int subtext_len = end-start+2;
char *subtext = malloc(sizeof(char)*subtext_len);
strncpy(subtext,&src[start],subtext_len-1);
subtext[subtext_len-1] = '\0';
return subtext;
}

Resources