When you are printing a tab character to the standard output using printf
in C, it outputs some space which is apparently 4 characters in length.
printf("\t");
Is there a way by which I can control the tab width in the above case?
When you are printing a tab character to the standard output using printf
in C, it outputs some space which is apparently 4 characters in length.
printf("\t");
Is there a way by which I can control the tab width in the above case?
That's something controlled by your terminal, not by 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.
A tab is a tab. How many spaces it consumes is a display issue, and depends on the settings of your shell.
If you want to control the width of your data, then you could use the width sub-specifiers in the printf
format string. For example,
printf("%5d", 2);
It's not a complete solution (if the value is longer than five characters, it will not be truncated), but it might be OK for your needs.
If you want complete control, you'll probably have to implement it yourself.
If your terminal supports proper ANSI escape sequences, there are escape sequences to set tab stops to any location on the screen. The escape sequence ESC [ 3 g
clears all tab stops, the escape sequence ESC H
sets the tab stop at a specific location.
Below is an POSIX example C program that provides a function that set's tab stops to the specified count of spaces. First all existing tabs are removed, then spaces are printed and in proper locations the tab stop is set. Then the cursor is rewind back to the start of the line.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
int writestr(int fd, const char *s) {
return write(fd, s, strlen(s)) == (ssize_t)strlen(s) ? 0 : -1;
}
int set_tab_stops(unsigned distance) {
assert(distance > 0);
// Using stdout here, stderr would be more reliable.
FILE *file = stdout;
const int fd = fileno(file);
// We have to flush stdout in order to use fileno.
fflush(file);
// Get terminal width.
// https://stackoverflow.com/questions/1022957/getting-terminal-width-in-c
struct winsize w = {0};
if (ioctl(fd, TIOCGWINSZ, &w) < 0) return -__LINE__;
const unsigned cols = w.ws_col;
// Remove all current tab stops.
if (writestr(fd, "\033[3g") < 0) return -__LINE__;
// Do horicontal tabs each distance spaces.
for (unsigned i = 0; i < cols; ++i) {
if (i % distance == distance - 1) {
if (writestr(fd, "\033H") < 0) return -__LINE__;
}
if (writestr(fd, " ") < 0) return -__LINE__;
}
// Clear the line and return to beginning of the line.
if (writestr(fd, "\033[1K\033[G") < 0) return -__LINE__;
return 0;
}
int main() {
set_tab_stops(10);
printf("1\t2\t3\t4\n");
set_tab_stops(5);
printf("1\t2\t3\t4\n");
}
With xfce4-terminal
the program outputs:
1 2 3 4
1 2 3 4