سؤال

I have the following program in C:

The main problem with the program is that after I perform the copy operation, a number of rubbish characters are displayed after the letters copied. I know this is because the destination variable is NOT properly null-terminated. However, if you inspect the code carefully, I am performing null-termination. Why is the problem still there?

هل كانت مفيدة؟

المحلول

strncpy does not guarantee that your destination string will be null-terminated after the copy. My approach would be to:

destination[ nob ] = '\0';

نصائح أخرى

So, uh, how do you think strlen() computes the length of a string? Do you think it requires termination?

Hint: it does. An array of characters is not a string in C unless it's terminated by a 0-character. All strlen() does is count the number of characters until it finds the terminator, so using it in logic to terminate a buffer in order to make it a string is a chicken-egg kind of situation.

Your problem is that you are mis-using strncpy(). This is a very easy thing to do wrong, since the function is slightly nuts from a typical (beginner) C programmer's point of view. It simply doesn't do what you would expect it to, from the name.

You should probably just do this manually, as long as you're certain that nob < sizeof destination - 1:

memcpy(destination, source, nob);
destination[nob] = '\0';

Matthew, when you already know the length of the string you are copying, you don't need strcpy or strncpy (which check each character looking for the \0 at the end). Instead you should use memcpy and then terminate the new string:

memcpy(destination, source, nob);
destination[nob] = '\0';

memcpy does not check for '\0' and so is faster.

Instead of:

destination[strlen(destination)] = '\0';

have:

destination[nob] = '\0';

strlen keeps reading until it finds the '\0' char.

This will work great after some really small modification:

char destination[18] = {'\0'};

Do not use strncpy, it is plain dangerous. As we can see from your example, programmers always forget to input the correct parameters to it, and they get corrupt strings as a result. This is an incredibly common bug.

strcpy() is safer, but not ideal either, since it has no boundary check. If used incorrectly it could lead to buffer overflows, which is a security concern. This is also a common bug.

The fastest and safest way to copy strings is through memcpy:

memcpy(destination, source, nob);
desitnation[nob] = '\0';

This is failing because strncpy copies only the first nob characters and does not append a trailing 0. Your attempt to add a trailing 0 with the strlen() on the destination string does not help, because it count characters until the 1st 0, and put a zero in that location (which will have no effect).

One way to "hack" a fix would be to clear your destination string:

memset( destination, 0, sizeof(destination));

There are probably much better solutions, including making your test for > 17 be > 18.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top