6

I have a c++ program and I use the tab character "\t" to organize my output to a human-readable columns. However, 8-spaces-wide column in bash is too narrow for me. How can I increase it?

Note: In C++ forums people say: "C++ just outputs the character and is not responsible for the visible output". In linux forums people say: "It is the program you use to output to terminal that is responsible for this, probably less or so."

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
yo'
  • 929
  • how are you viewing your program on the terminal, is it using a pager such as less or and editor like vi? – iruvar Oct 24 '12 at 16:44
  • No, no "viewer". I open the terminal and type ./a.out or whatever is the name of the binary. – yo' Oct 24 '12 at 16:45
  • If you don't use any viewer, it's the programs role to format the output accordingly. If you were to use a pager or a text editor or processor, maybe, but just MAYBE, this intermediary software could represent tabs as N (N being customizable) spaces. – Spidey Oct 24 '12 at 17:17
  • If I redirect the ouput to a file like ./a.out > file.txt, then the file contains the tab character. So obviously, the program sends the tab character to the terminal and it's a role of the terminal to typeout it correctly. – yo' Oct 24 '12 at 17:20
  • Also, see http://unix.stackexchange.com/questions/46368/set-tab-width-in-gui-terminal?rq=1 – Alex Leach Oct 24 '12 at 17:37

4 Answers4

4

So, the printed tab character is fixed within the source code of the program. I don't think that the display of the tab character in bash can be edited in a shell setting.

I'm just guessing here, but I think the representation of the tab character is embedded within the character encoding set that your terminal program is using. The ASCII character set defines the tab character, but the UTF-8 character set doesn't seem to. I don't think any character encoding set uses a different width for the tab character, so I think you're out of luck unless you want to write your own character set and use it, but that sounds like a headache waiting to happen.

Instead, have you tried the pr command?

PR(1) User Commands PR(1)

NAME pr - convert text files for printing

To swap tab characters for 10 spaces, you could do this:-

./a.out | pr --expand-tabs=10 -t
Alex Leach
  • 7,910
  • pr paginates the output, which is frowned upon. Can this be disabled? – yo' Oct 24 '12 at 17:31
  • @tohecz the -T option disable pagination – derobert Oct 24 '12 at 17:33
  • -t option. Will update answer... – Alex Leach Oct 24 '12 at 17:33
  • Ok, so it seems to help, thanks. However, having to pipe it seems a bit strange to me and means you have to call it another way to output it tab-seperated to a file etc. – yo' Oct 24 '12 at 17:38
  • Well, you could output it to file once, complete with tabs, and then run pr .. directly on the tab-delimited file. e.g. ./a.out > output.txt ; pr --expand-tabs=10 -t output.txt – Alex Leach Oct 24 '12 at 17:43
4

You can change the tab stops in your terminal using the terminal database, which you can access several ways from C++ (for example, ncurses). You can also access it from shell using tput.

You'd want to start by clearing the tabs (tput tbc). Then move the cursor to each column you want a tab stop in (tput hpa 10 for column 10, for example). Then finally set the tab stop (tput hts). Repeat the positioning and tab setting for each tab stop you want. Example:

echo -e '0\t1\t2\t3\t4\t5\t6\t7\t8'
tput tbc
for ((i=0; i<`tput cols`; i+=10)); do
    tput hpa $i
    tput hts
done
tput hpa 0
echo -e '0\t1\t2\t3\t4\t5\t6\t7\t8'
derobert
  • 109,670
  • So I can put something like tput tbc tput hpa 10 tput hts tput hpa 20 tput hts ... into my .bashrc and just be happy? – yo' Oct 24 '12 at 17:46
  • @tohecz yes, you can put that in your bashrc, but that'll change tabstops every bash shell you have. You may not want it for all your shells. You can also use ncurses, etc. in your program, and then just have it take effect when you run your program. – derobert Oct 24 '12 at 17:48
3

C++ isn't responsible for the width. I had a longer response typed up but it really became unnecessary when I did a test...

Basically, use tabs (part of the ncurses5 package)... e.g.

zsh> tabs 4 # 4 space width tabs
zsh> ./a.out

This will format to your width you want automatically. No need to pipe (which doesn't help if you have interactive work).

derobert
  • 109,670
sparticvs
  • 2,739
  • 16
  • 22
  • I've edited in which package the tabs command comes from in case someone doesn't have it installed. Feel free to revert my edit if you do not approve. – derobert Oct 24 '12 at 19:25
  • Thanks @derobert I wasn't sure as it came preinstall on my CentOS 6 box and I didn't check to see what provided it. – sparticvs Oct 24 '12 at 22:02
2

As illustrated in the other answers, the tabs utility is the simpler way to specify tab stops for applications (such as your shell) which do not set their own tab stops. POSIX specifies a tabs utility, (as well as tput), but has nothing to say about terminfo or the behavior of tput for this purpose. (X/Open Curses, which is a separate standard, does have something to say).

But to use those tab stops, you should also ensure that your terminal is setup to use hardware tabs. If you do stty -a, look for tab0 in the output:

speed 38400 baud; rows 40; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

According to the stty manual, you should be able to set tab0 or tab3. POSIX defines tab1 and tab2, but only tab0 (hardware tabs) and tab3 (software tabs) are useful to you.

tab0 tab3
Select tab expansion policy. tab0 disables tab expansion, while tab3 enables it.

Further reading:

Thomas Dickey
  • 76,765