I am writing a program which takes in user input character by character and print it out at the end:
#include <stdio.h>
#include <stdlib.h>
#define FACTOR 2
int main(void) {
printf("Enter line: ");
int curr_size = 10;
char curr_char = 0;
char *ptr = malloc(curr_size * sizeof(char));
int num_of_chars = 0;
while (1) {
int res = scanf(" %c", &curr_char);
if (res == EOF) {
break;
}
if (res != 1) {
printf("Error: %c is not a character", res);
break;
}
if (num_of_chars == curr_size) {
curr_size = FACTOR * curr_size;
ptr = realloc(ptr, curr_size);
}
ptr[num_of_chars] = curr_char;
num_of_chars++;
}
printf("%s\n", ptr);
return 0;
}
However, I notice that whenever I enter a line more than 10 characters (which trigger realloc), there is a unknown character appended at the end of my line when outputing:
If I change ptr[num_of_chars] = curr_char;
to *(ptr + num_of_chars) = curr_char;
the character disappear, may I know why and how to fix it? Thanks in advance.
Taking into account this if statement
if (res == EOF) {
break;
}
the following if statement
if (res != 1) {
printf("Error: %c is not a character", res);
break;
}
does not make sense. Moreover you are trying to output an integer returned by the function scanf
as a character.
In general the function realloc
can return NULL. In this situation there will be a memory leak because the previous value of the pointer ptr
was overwritten
ptr = realloc(ptr, curr_size);
and this statement
ptr[num_of_chars] = curr_char;
will invoke undefined behavior.
Also you are trying to output the character array as a string
printf("%s\n", ptr);
but you did not append the array with the terminating zero character.
You should in this case use the call at least like
printf("%*.*s\n", num_of_chars, num_of_chars, ptr);
or you have to append the terminating zero character.
And you should free the allocated memory.
The program can look like
#include <stdio.h>
#include <stdlib.h>
#define FACTOR 2
int main(void)
{
size_t curr_size = 10;
char *ptr = malloc( curr_size * sizeof( char ) );
ptr[0] = '\0';
char c;
printf( "Enter line: " );
size_t i = 0;
for ( ; scanf( "%c", &c ) == 1 && c != '\n'; i++ )
{
if ( i == curr_size )
{
char *tmp = realloc( ptr, curr_size * FACTOR );
if ( tmp == NULL ) break;
curr_size *= FACTOR;
ptr = tmp;
}
ptr[i] = c;
}
// i == curr_size ? ptr[i-1] = '\0' : ( ptr[i] = '\0' );
// puts( ptr );
printf( "%*.*s", ( int )i, ( int )i, ptr );
free( ptr );
return 0;
}