0

I'm trying to remove the file extension from a file so I can rename the file with the substring "opt.s". I do this with following simple example program:

 char in[5] = "hel.s";
 char test[40];
 strncpy(test,in,strlen(in)-2);
 char result[50];
 strcpy(result,strcat(test,"opt.s"));
 printf(" %s ",result);

The output i get differs but usually looks something like the following:

 helþ(opt.s 

So basically random numbers appear in between "hel" and "opt.s". What is the cause of this? Did I use strcpy wrong or is strcat causing the problem?

0

2 Answers 2

2

This is incorrect:

char in[5] = "hel.s";

The string takes six, not five, characters (the sixths one is for null terminator). Without it the string is unterminated, causing strlen, strcat, and other functions that work on terminated strings to fail with undefined behavior.

To fix, remove 5 from the declaration, and let the compiler decide on the length for you:

char in[] = "hel.s";

In addition, your use of strncpy is invalid: it does not implicitly append null terminators

No null-character is implicitly appended at the end of destination if source is longer than num. Thus, in this case, destination shall not be considered a null terminated C string (reading it as such would overflow).

This line

strncpy(test,in,strlen(in)-2);

always produces an unterminated string, causing subsequent call of strcat to fail. To fix this, you need to add a terminator yourself:

size_t len = strlen(in)-2;
memcpy(test, in, len); // Do not use strncpy
test[len] = '\0';
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this was exactly what I was looking for. Helped on multiple levels
What happens in the case where you need to take a part of a string and not the last / first part? Then you need to use strncpy(test,input+4,5), if you want to extract the substring from char 4 until char 9, I suppose.
@John strncpy is for strings of fixed length - something that is not common any longer (and hasn't been common for quite a while now). Since you know for sure that the part you are taking is within the body of the string (i.e. does not cross the end of the string) you are better off with plain memcpy.
2
char in[5] = "hel.s";

in is NOT a string: it does not have a terminating '\0' char. You cannot use in with string functions.

strncpy(test, in, strlen(in) - 2); // invalid use of strlen

However, strncpy() is not a string function (it doesn't need a terminating NUL in the src array; it doesn't necessarily write terminating NUL in the dst array).
If it worked as I think you expected, the resulting test array is also NOT a string ... and you cannot use it with string functions.

strcpy(result, strcat(test, "opt.s")); // invalid use of strcat

2 Comments

Shouldn't 5 be just ommited?
It could be, of course. In this particular case, you can conveniently use sizeof(in) to obtain the size of the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.