I have a general understanding question! Here is my code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
int main() {
// read user input
char input[64] = {0};
read(0, input, 64);
printf("You've entered ");
printf(input);
char newbuf[128];
char smallbuf[8];
// copy into smallbuf 8 bytes of input
memcpy(smallbuf, input, 8);
// send smallbuf of 8 bytes as string into newbuf
sprintf(newbuf, "%s", smallbuf);
// print newbuf
printf(&newbuf[0]);
return 0;
}
The behavior I get with 7 chars is okay, it does print 7 chars:
$ gcc a.cpp -o a.out && ./a.out
1234567
You've entered 1234567
1234567
1234567
But with 8 chars it prints a lot more of them and I'm wondering why does it do this:
$ gcc a.cpp -o a.out && ./a.out
12345678
You've entered 12345678
1234567812345678
Thank you for explaining me! :)
CodePudding user response:
Code is attempting to print a character array as if it was a string leading to undefined behavior.
smallbuf[]
does not certainly contain a null character, so it is not a string.
"%s"
expects a matching pointer to a string.
Either account for a null character
char smallbuf[8 1];
memcpy(smallbuf, input, 8);
smallbuf[8] = '\0';
printf("%s", smallbuf);
or limit output with a precision. That prints a character array up to N characters or a null character.
char smallbuf[8];
memcpy(smallbuf, input, 8);
printf("%.8s", smallbuf);
Similar issue applies to printf(input);
Do not code printf(input);
as that may lead to undefined behavior when input[]
contains a %
.
// printf(input);
printf("%s", input);
Better code would examine the return value of read(0, input, 64)
.