简体   繁体   中英

questions regarding string functions like strcat(), strncpy(),strncat()?

code 1

int main()
{
    char str[]="abc";
    char str1[]="hello computer";
    strcat(str,str1);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

output- abchello computer

code 2

int main()
{
    char str[100];  //notice the change from code 1
    char str1[]="hello computer";
    strcat(str,str1);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

output- @#^hello computer

code 3

int main()
{
    char str[100];
    char str1[]="hello computer";
    strncpy(str,str1,5);
    str[5]='\0';   //external addition of NULL
    printf("the copied string is : %s\n",str);
    return 0;
}

output- hello

code 4

int main()
{
    char str[100]="abc";
    char str1[]="hello computer";
    strncat(str,str1,5);
    printf("the concatenated string is : %s\n",str);
    return 0;
}

output- abchello

QUESTIONS

Q-1) Why abchello computer is displayed in code 1 and @#^hello computer in code 2 ? From where the garbage @#^ is coming?

Q-2) Why external addition of NULL '\\0' is required in strncpy() but not in strncat() as shown in code 3 and code 4 respectively?

NOTE- If in code 4 I do char str[100]; then @#^hello is displayed,but still the string is ended without addition of NULL

The first example writes beyond the end of str and so has undefined behaviour.

The second example uses strcat which demands two null-terminated strings as arguments. One of your arguments does not meet that requirement because you failed to initialise it.

The third example does not copy a null terminator because that is how strncpy is designed. As you can discern from the documentation, strncpy does not write a null terminator if the destination buffer is smaller than the source string.

As for the fourth example, strncat differs from strncpy in that it always copies a null-terminator.

I do recommend that you refer closely to the documentation of these functions.

Code 1

char str[]="abc";
char str1[]="hello computer";
strcat(str,str1);

This overflows str . The behavior is undefined and any output can be assumed (in reality, probably str1 is being overwritten by itself, that's why you see abshello computer as output).

Code 2

char str[100];  //notice the change from code 1
char str1[]="hello computer";
strcat(str,str1);

You see garbage before hello computer because str is uninitialized. It so happens that it had contained "@#^" at the time of your test before its first NUL.

Code 3

char str[100];
char str1[]="hello computer";
strncpy(str,str1,5);
str[5]='\0';   //external addition of NULL

This is correct. strncpy copies the first five characters from "hello computer" and doesn't NUL-terminate it. You should do that yourself (as you have done). For further reference, from man page of strcpy :

The strcpy() function copies the string pointed to by src, including the terminating null byte ('\\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.)

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

Code 4

char str[100]="abc";
char str1[]="hello computer";
strncat(str,str1,5);

One difference between strncpy and strncat is that strncat NUL-terminates the resulting string. From man page of strncat :

As with strcat(), the resulting string in dest is always null-terminated.

As David said, for strcat it expects null terminated string so thatmay be he possible reason for the garbage value.

For your code 3, the '\\0' character at the last of the string represents a char array as string, with out '\\0' terminating it is just a char array not a valid string. Since you are printing by using %s , compiler requires to be it as string.

Q-1) Why abchello computer is displayed in code 1 and @#^hello computer in code 2? From where the garbage @#^ is coming?

In Code2: "char str[100] contains uninitialized garbage characters".

Try running the Code2 program multiple times. You may see that the garbage characters at the beginning of the string change every time you run it. char str[100] reserves a place in memory where you can store 100 characters in a row, but it does not clean it out for you. Anything left in memory from a previous program is often referred to as 'garbage'. That memory almost certainly contains random data from the last time the memory was used. Sometimes you can even find readable strings in uninitialized memory like this.

When you run strcat, the program needs to figure out where the end of the string in 'str' is. The problem is, there was never a proper string put into str - it is just full of garbage. The program starts at the beginning of the char str[100] buffer and looks for a '\\0' character that indicates the end of the string. It will find one eventually (a random '\\0\\ will eventually shown up somewhere in memory) and declare that to the be the end of the first string. It now considers everything before the first '\\0' to be part of the official string.

Try this: add the following line right before the strcat: str[0]='\\0'; The program should now run without showing the garbage characters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM