Reputation: 135
I am writing a program which allows the user to enter a number between 1 and 9 inclusive. Then display the width of output according to the number entered by the user. E.g. if 1 is entered, the program should print out "Your input is 1". If the 5 is entered, the program should print out "Your input is XXXXX5" [X = space]
So what I did what initializing a char array of size of the integer entered which is responsible for the width. Then initialize the char array with ' ' accordingly using for loop.
Everything works fine with number 1 to 8. But when I entered 9, there would be random characters before the digit such as "Your input is �@9".
What is happening? It seems like the compiler did not add the string terminator for the case of 9. Then it works fine when I manually set the last char to be '\0'.
Here are my codes:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char * argv[]){
int num;
do{
//prompt user to enter an int
printf("Please enter an integer between 1 and 9 inclusive: ");
scanf(" %d", &num);
//check if the number is between 1 and 9
if (num < 1 || num > 9) puts("You have enter an invalid integer! Try again!");
//ask for input unless valid
}while(num < 1 || num > 9);
char space[num]; //max width is num-1 but 1 more slot for string terminator
//initiate the string according to the width
for (int i = 0 ; i < num - 1 ; i++){
space[i] = ' ';
}
//space[num - 1] = '\0';
//display int according to the width
printf("Your input is %s%d\n", space, num);
return 0;
}
Upvotes: 2
Views: 994
Reputation: 4035
Printing the string with %s
format specifier looks for the NULL terminator '\0'
and keep on printing the characters till it finds the NULL terminator
.
Since the space[]
array is local, it can have any garbage value. The last element may not be '\0'
and hence you are seeing the strange characters in the output.
For the cases which are working is hence not a predictable behavior.
Hence you need to explicity terminate the string with '\0'
, Or you can do a memset in the beginning before using the array.
memset(space, 0, sizeof(space));
Upvotes: 1
Reputation: 2446
The width field can be used to specify a field within which to print the value. Following % are width and precision fields. %5d
would always use a width of 5. With %*d
the asterisk allows for a variable width argument, in this example num + 1
. The width needs an integer type.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char * argv[]){
int num = 0;
do{
//prompt user to enter an int
printf("Please enter an integer between 1 and 9 inclusive: ");
if ( 1 != scanf(" %d", &num)) {
num = 0;
//input was not an int so check for EOF
if ( EOF == getchar ( )) {
return 0;
}
//clean pending characters up to newline
while ( '\n' != getchar ( )) { }
}
//check if the number is between 1 and 9
if (num < 1 || num > 9) puts("You have enter an invalid integer! Try again!");
//ask for input unless valid
}while(num < 1 || num > 9);
//display int according to the width
printf("Your input is:%*d\n", num + 1, num);
return 0;
}
Upvotes: 2
Reputation: 1458
When you declare your char array in the stack, its values are not initialized at 0, meaning those slots contain whatever was on the stack at the moment.
Said otherwise, the surprising part is not the behavior at 9 but at every other value, since this char array's contents prior to overwriting them are purely undefined.
You have to initialize it yourself at 0 if you want a certain result.
Upvotes: 1