Milk_QD
Milk_QD

Reputation: 135

Weird behavior for char array in C

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

Answers (3)

Sumit Trehan
Sumit Trehan

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

xing
xing

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

Adalcar
Adalcar

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

Related Questions