Your posted code does not have a buffer overflow, but you are right that the input from one input prompt "overflows" into the next input prompt.
What is happening is the following:
Since your input string consists of 160 characters (161 characters including the null terminating character), when you first enter that input, it will fit entirely inside the array nome
, so the line
scanf("%200s", nome);
will read this input entirely.
However, when you enter that input a second time, this time at the second input prompt, the line
scanf("%14s", cpf);
will only read the first 14 characters of that input and leave the remaining 146 characters on the input stream.
Therefore, the line
scanf("%100s", senha);
will read 100 of the remaining 146 characters of the input stream and write them into senha
. So you are correct in saying that the second input prompt "overflows" into the third input prompt.
If you want to prevent this "overflow" from happening, you will have to discard all remaining characters on the line before the next input prompt, for example by calling:
scanf( "%*[^\n]" );
However, I generally do not recommend using the function scanf
for user input, as that is not what it is designed to be used for.
Also, judging form the comments you made in the comments section, you want to be able to read entire lines that may be separated by spaces, instead of reading single words. However, the %s
scanf
format specifier will only read a single word.
For this reason, it is probably better for you to use the funtion fgets
. This function will always attempt to read an entire line at once, including the newline character, instead of only a single word.
However, when using fgets
, you will probably want to remove the newline character from the input. See the following question on how to do that:
Removing trailing newline character from fgets() input.
In the program below, I have created a function get_line_from_user
which will read a single line from the user using fgets
, discard the newline character, and if the line does not fit into the buffer, it willl also discard the rest of the line:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void get_line_from_user( char *buffer, int buffer_size );
int main()
{
char nome[201] = {0};
char cpf[15] = {0};
char senha[101] = {0};
printf( "Input Phase: \n\n" );
//read inputs
printf( "Nome: " );
get_line_from_user( nome, sizeof nome );
printf( "Cpf: " );
get_line_from_user( cpf, sizeof cpf );
printf( "Senha: " );
get_line_from_user( senha, sizeof senha );
printf( "\n\nOutput Phase: \n\n" );
//output the results
printf("nome: %s\n", nome);
printf("cpf: %s\n", cpf);
printf("senha: %s\n", senha);
return 0;
}
//This function will read exactly one line of input from the
//user and discard the newline character. If the line does
//not fit into the buffer, it will also discard the rest of
//the line from the input stream.
void get_line_from_user( char *buffer, int buffer_size )
{
char *p;
//attempt to read one line of input
if ( fgets( buffer, buffer_size, stdin ) == NULL )
{
printf( "Error reading from input\n" );
exit( EXIT_FAILURE );
}
//attempt to find newline character
p = strchr( buffer, '\n' );
//determine whether entire line was read in (i.e. whether
//the buffer was too small to store the entire line)
if ( p == NULL )
{
int c;
//discard remainder of line from input stream
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
}
else
{
//remove newline character by overwriting it with
//null character
*p = '\0';
}
}
This program has the following behavior:
Input Phase:
Nome: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
Cpf: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
Senha: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
Output Phase:
nome: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
cpf: aaaaaaaaaaaaaa
senha: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaassssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
As you can see, the input from one input prompt no longer overflows into the input of another input prompt.
And it now also works with spaces in the input:
Input Phase:
Nome: This is a test
Cpf: Another test
Senha: Yet another test
Output Phase:
nome: This is a test
cpf: Another test
senha: Yet another test