Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C program output not formatting properly(using \t)

Tags:

c

I am just wondering and confused as too why my output is messed up. The code is below. I am a beginner so please excuse my lack of skill. Any help would be very much appreciated.

#include <stdio.h>

int main(int argc, char *argv[]) 
{

    for (int i = 1; i <= 10; i++)
    {

        for (int j = 1; j <= i; j++)
        {
            printf("*");
        }
        printf("\t");
        for (int k = 1; k <= 11-i; k++)     
        {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

Gives this output:

enter image description here

My desired output is this:
enter image description here

like image 330
Iman Avatar asked Jun 29 '18 20:06

Iman


People also ask

What is the work of \t in c?

\t (Horizontal tab) – We use it to shift the cursor to a couple of spaces to the right in the same line.

What does \t do in printf?

printf simply sends a \t to the output stream (which can be a tty, a file, etc.). It doesn't send a number of spaces.

What does the special character '\ t do?

It is used in representing certain whitespace characters: "\t" is a tab, "\n" is a newline, and "\r" is a carriage return. Conversely, prefixing a special character with "\" turns it into an ordinary character. This is called "escaping".

How do I give a space in printf?

In C language, we can directly add spaces. printf(“ ”); This gives a space on the output screen.


6 Answers

The precision and width fields can be use for formatting. Precision will print up to the specified number of characters and width will print at least the specified number of characters. Using an asterisk in either field allows an argument for a variable number of characters.

#include <stdio.h>

int main( void) {
    char asterisk[] = "***********";

    for (int i = 1; i <= 10; i++)
    {
        printf ( "%.*s", i, asterisk);//print up to i characters
        printf ( "%*s", 15 - i, " ");//print at least 15 - i characters
        printf ( "%.*s", 11 - i, asterisk);
        printf("\n");
    }
    return 0;
}
like image 28
user3121023 Avatar answered Oct 06 '22 20:10

user3121023


\t stops at the next reachable tab position, which by default are multiples of 8.

Therefore, if you print ***, it will skip to column 8, but if you print *********, you are already past 8, so it skips to column 16.

like image 157
Aganju Avatar answered Oct 06 '22 18:10

Aganju


... why my output is messed up (?)

Code uses a tab '\t' which only aligns to the next tab-stop - usual every 8 columns and the stars needed exceed 8.


With judicious use of the '-' flag, field width and precision, code can be simplified to print an array of characters.

#include <stdio.h>
#include <string.h>

int main(void) {
  int n = 10;
  char stars[n];
  memset(stars, '*', n);

  for (int i = 0; i < n; i++) {
    //       +------------- - flag: pad on right     
    //       |+------------ field width: min characters to print, pad with spaces
    //       || +--------+- precision: max numbers of characters of the array to print
    printf("%-*.*s     %.*s\n", n, i + 1, stars, n - i, stars);
    //                          |  ^^^^^         ^^^^^ precision
    //                          +--------------------- field width
  }
}

Output

*              **********
**             *********
***            ********
****           *******
*****          ******
******         *****
*******        ****
********       ***
*********      **
**********     *

Note: stars is not a string as it lacks a null character. Use of a precision with "%s" allows printf() to use a simple character array. Characters from the array are written up to (but not including) a terminating null character.

like image 20
chux - Reinstate Monica Avatar answered Oct 06 '22 18:10

chux - Reinstate Monica


A tab-stop is not a fixed-width space (e.g. the same as 4 spaces or 8 spaces), it means that the output device should move the caret (or print-head) to the next column position for tabular data. These column positions are at fixed regular intervals, that's why \t** and **\t have different printed widths:

String        Output:
"\t**a"       "    **a" (7 wide)
"**\ta"       "**  a"   (5 wide)
like image 39
Dai Avatar answered Oct 06 '22 20:10

Dai


As others have mentioned, printing a tab character move the cursor to the next tab stop, not a certain number of spaces.

After printing the first set of asterisks, print spaces until you've printed enough characters to space out as far as you need.

    for (int j = 1; j <= 10; j++)
    {
        if (j<i) {
            printf("*");
        } else {
            printf(" ");
        }
    }
like image 31
dbush Avatar answered Oct 06 '22 18:10

dbush


I would do like this:

const int rows = 10;
for (int i = 0; i < rows; i++) {
    const int width = 10;
    const int space = 5;
    const int totalw = 2*width + space;
    for (int j = 0; j < totalw; j++) {
        char ch = j<=i || (j>=width+space && j<(totalw-i)) ? '*' : ' ';
        printf("%c", ch);
    }
    printf("\n");
}

And just for completeness, even though mentioned in other answers. The '\t' character does not have a fixed width.

like image 28
klutt Avatar answered Oct 06 '22 20:10

klutt