【问题标题】:printf() \t optionprintf() \t 选项
【发布时间】:2011-10-02 12:40:07
【问题描述】:

当您在 C 中使用 printf 将制表符打印到标准输出时,它会输出一些长度明显为 4 个字符的空格。

printf("\t");

在上述情况下,有什么方法可以控制标签宽度?

【问题讨论】:

    标签: c printf


    【解决方案1】:

    标签是一个标签。它占用多少空间是一个显示问题,取决于你的 shell 的设置。

    如果您想控制数据的宽度,那么您可以使用printf 格式字符串中的width 子说明符。例如,

    printf("%5d", 2);
    

    这不是一个完整的解决方案(如果值超过五个字符,则不会被截断),但它可能满足您的需求。

    如果您想要完全控制,您可能必须自己实现它。

    【讨论】:

    • 实际上对于字符串,您可以截断:printf("%5.5s","abcdefg"); 将输出“abcde”。如果在字符串少于 5 个字符的情况下始终希望输出左对齐,请使用 "%-5.5s"
    • @proFromDover :如果您可以将自己限制为字符串,那没关系,是的。
    【解决方案2】:

    这是由您的终端控制的,而不是由 printf 控制的。

    printf 只是将\t 发送到输出流(可以是 tty、文件等)。它不会发送多个空格。

    【讨论】:

    • +1,在我看来,这是一个比已被接受的答案更合适的答案。
    【解决方案3】:

    如果您的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
    

    【讨论】:

      猜你喜欢
      • 2012-04-05
      • 2018-04-25
      • 2012-12-01
      • 2010-10-19
      • 2019-10-19
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多