【发布时间】:2011-10-02 12:40:07
【问题描述】:
当您在 C 中使用 printf 将制表符打印到标准输出时,它会输出一些长度明显为 4 个字符的空格。
printf("\t");
在上述情况下,有什么方法可以控制标签宽度?
【问题讨论】:
当您在 C 中使用 printf 将制表符打印到标准输出时,它会输出一些长度明显为 4 个字符的空格。
printf("\t");
在上述情况下,有什么方法可以控制标签宽度?
【问题讨论】:
标签是一个标签。它占用多少空间是一个显示问题,取决于你的 shell 的设置。
如果您想控制数据的宽度,那么您可以使用printf 格式字符串中的width 子说明符。例如,
printf("%5d", 2);
这不是一个完整的解决方案(如果值超过五个字符,则不会被截断),但它可能满足您的需求。
如果您想要完全控制,您可能必须自己实现它。
【讨论】:
printf("%5.5s","abcdefg"); 将输出“abcde”。如果在字符串少于 5 个字符的情况下始终希望输出左对齐,请使用 "%-5.5s"
这是由您的终端控制的,而不是由 printf 控制的。
printf 只是将\t 发送到输出流(可以是 tty、文件等)。它不会发送多个空格。
【讨论】:
如果您的terminal 支持正确的ANSI escape sequences,则可以使用转义序列将tab stops 设置为屏幕上的任何位置。转义序列ESC [ 3 g 清除所有制表位,转义序列ESC H 将制表位设置在特定位置。
下面是一个POSIX 示例C 程序,它提供了一个函数,可以将制表位设置为指定的空格数。首先删除所有现有的制表符,然后打印空格并在适当的位置设置制表位。然后光标回退到行首。
#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");
}
使用xfce4-terminal,程序输出:
1 2 3 4
1 2 3 4
【讨论】: