You can test on your own:
#include <stdio.h>
int main(void) {
char nomeSobrenome[40];
printf("Insira seu nome e seu sobrenome:\n");
scanf("%[A-Z a-z 0-9 !-_]s", nomeSobrenome);
printf("%s\n", nomeSobrenome);
for (int i = 0; i < 40; i++) printf("%c = %d, ", nomeSobrenome[i], nomeSobrenome[i]);
}
The scanf()
always deliver a string complete, which obviously includes the terminator.
No matter how much formatting is applied, this aspect being asked does not change. What will change is how to interpret the input or how to manipulate the buffer, but the end result is always equal under normal conditions. This function ensures a string well formed or gives an error (in general the correct is to check if everything occurred well before using the data).
If you used scanf("%s", nomeSobrenome);
would do the same for the terminator.
In C there is no type string, he only works with one array of char
and this does not include its size, which was a design unhappy that we have to live. The only way to identify the end of string in C default is to find the terminator, so any supposed string that does not have a terminator is a mistake.
The scanf()
can corrupt memory if it does not have a specific limit, in your example should be 39 (scanf("%39s", nomeSobrenome);
). If someone types more than this they may have problems.
If you have more different data read, each data will go to a variable and will be formed with the terminator.
What I did in the code above was to print all 40 bytes you reserved in the variable sobreNome
. I had it printed as a character (%c
) and then as number to be more obvious (%d
). What comes after the terminator can come something that was already in the memory before.
If you used the printf()
with %s
which is the standard for string or another function that considers the terminator would stop the loop as soon as it finds the \0
, which is correct under normal conditions.
To view better and not get junk memory now I will initialize the variable:
#include <stdio.h>
int main(void) {
char nomeSobrenome[40] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
printf("Insira seu nome e seu sobrenome:\n");
scanf("%[A-Z a-z 0-9 !-_]s", nomeSobrenome);
printf("%s\n", nomeSobrenome);
for (int i = 0; i < 40; i++) printf("%c = %d\n", nomeSobrenome[i], nomeSobrenome[i]);
}
Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.
This can be seen debugging the program. Yes will still put the
\0
, is an indicator to know where the text ends, because otherwise when writingola
in a stringsobrenome[20]
I was gonna leave 17 garbage spaces and print this– Fábio Morais
Sorry, I didn’t quite understand your answer. The size of the vector, in this example, is not the focus. What I want to know is this: if I limit the scanf, does the program automatically set the null character? I know it puts automatically without limiting the scanf. The doubt is with the limitation. Hug.
– WillBill
My answer says so. "Yes will rent in the same
\0
"– Fábio Morais
I was in doubt because 0 comes before ! in the ASCII table.
– WillBill
It’s just limiting the
scanf
that is, what he will read. Because he thought he would not put the\0
?? The\0
is placed AFTER having read, after thescanf
....– Fábio Morais
You’re right, cleared my doubt! I didn’t think about the order. Thanks!!!
– WillBill