使用C语言中的终端列格式化输出

使用C语言中的终端列格式化输出,c,C,我正在尝试使用C中的终端列大小,使用write格式化文件列表。我试图将输出格式化为如下所示,而不使用printf或其他格式化函数。 这就是我得到的 这是我的密码 #include <stdio.h> #include <sys/ioctl.h> /* ioctl, TIOCGWINSZ */ #include <err.h> /* err */ #include <fcntl.h> /* open */ #include <st

我正在尝试使用C中的终端列大小,使用
write
格式化文件列表。我试图将输出格式化为如下所示,而不使用
printf
或其他格式化函数。

这就是我得到的

这是我的密码

#include <stdio.h>
#include <sys/ioctl.h>  /* ioctl, TIOCGWINSZ */
#include <err.h>    /* err */
#include <fcntl.h>  /* open */
#include <string.h>
#include <unistd.h>

size_t  ft_strlen(const char *s)
{
    size_t  i;

    i = 0;
    while (s[i])
        i++;
    return (i);
}

int get_cols()
{
    struct winsize ws;
    int fd;
    int cols;

    cols = 0;
    /* Open the controlling terminal. */
    fd = open("/dev/tty", O_RDWR);
    if (fd < 0)
        err(1, "/dev/tty");

    /* Get window size of terminal. */ 
    if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
        err(1, "/dev/tty");
    close(fd);
    cols = ws.ws_col;
    return (cols);
}

void    print_item(const char *str, int num_sp)
{
    char sp = ' ';

    write(1, str, ft_strlen(str));
    while (num_sp--)
        write(1, &sp, 1);
}

int get_max_strlen(const char *list[])
{
    int len = 0;
    int i = 0;

    while (list[i])
    {
        if (ft_strlen(list[i]) > len)
            len = ft_strlen(list[i]);
        i++;
    }
    return (len);
}

void    print_list(const char *list[], int cols)
{
    int max_len = get_max_strlen(list);
    int i = 0;
    int curr_len;
    int tmp_cols = cols;

    while (list[i])
    {
        curr_len = ft_strlen(list[i]);
        if (curr_len < tmp_cols)
        {
            print_item(list[i], max_len - curr_len + 1); //+1 for space
            tmp_cols -= curr_len;
        }
        else
        {
            write(1, "\n", 1);
            tmp_cols = cols;
        }
        i++;
    }
}

int main()
{
    const char *list[] = 
    {
        "21sh", "21sh.fr.pdf", "author", "ft_auto_misc.o", "ft_auto_search.o",
        "ft_auto_utils.o", "ft_bck_i_search.o", "ft_cd.o", "ft_cmd_utils.o",
        "ft_commands.o", "ft_ctrl_c_signal_handler.o", "ft_ctrl_keyboard.o",
        "ft_ctrl_terminal.o", "ft_cut.o", "ft_echo.o", "ft_env.o", "ft_env_utils.o",
        "ft_execute.o", "ft_export.o", "ft_free.o", "ft_get_data.o", "ft_hash_table.o",
        "ft_hash_table_utils.o", "ft_here_doc.o", "ft_here_doc_utils.o", "ft_history.o",
        "ft_hist_utils.o", "ft_logical_op.o","ft_manage_buff.o", "ft_manage_hist.o", 
        "ft_manage_pipes.o", "ft_more_utils.o", "ft_parenthesis.o", "ft_parenthesis_utils.o",
        "ft_redirection.o", "ft_redirection_utils.o", "ft_signals.o", "ft_sub.o",
        "ft_term_utils.o", "ft_utils.o", "includes", "libft", "main.o", "Makefile",
        "nbproject", "README.md", "src", "TODO", 
        0
    };

    print_list(list, get_cols());
    return 0;
}
#包括
#包括/*ioctl、TIOCGWINSZ*/
#包括/*错误*/
#包括/*开放*/
#包括
#包括
尺寸英尺(常量字符*s)
{
尺寸i;
i=0;
而(s[i])
i++;
回报(i);
}
int get_cols()
{
结构winsize ws;
int-fd;
int cols;
cols=0;
/*打开控制终端*/
fd=打开(“/dev/tty”,O_RDWR);
如果(fd<0)
错误(1,“/dev/tty”);
/*获取终端的窗口大小。*/
if(ioctl(fd、TIOCGWINSZ和ws)<0)
错误(1,“/dev/tty”);
关闭(fd);
cols=ws.ws_col;
返回(cols);
}
无效打印项(常量字符*str,整数)
{
char sp='';
写(1,str,ft_strlen(str));
while(num_sp--)
写入(1和sp,1);
}
int get_max_strlen(常量字符*列表[])
{
int len=0;
int i=0;
while(列表[i])
{
如果(ft_strlen(列表[i])>len)
len=ft_strlen(列表[i]);
i++;
}
返回(len);
}
无效打印列表(常量字符*列表[],整数列)
{
int max_len=获取最大值(列表);
int i=0;
国际货币;
int tmp_cols=cols;
while(列表[i])
{
curr_len=ft_strlen(列表[i]);
如果(当前长度
打印列表的循环应如下所示:

while (list[i])
{
    curr_len = ft_strlen(list[i]);
    if (curr_len > tmp_cols)
    {
        write(1, "\n", 1);
        tmp_cols = cols;
    }

    // Always print the item. Do not skip it.
    print_item(list[i], max_len - curr_len + 1); //+1 for space
    tmp_cols -= maxlen+1;  <=== Not only curr_len
    i++;
}
while(列表[i])
{
curr_len=ft_strlen(列表[i]);
如果(当前>tmp)
{
写入(1,“\n”,1);
tmp_cols=cols;
}
//始终打印项目。不要跳过它。
打印项目(列表[i],最大长度-当前长度+1);//+1表示空格

tmp\u cols-=maxlen+1;谢谢,不知何故,最后一个项目会打印额外的空格,我已将
\n
更改为
\r
。是的,您会为每个项目打印填充空格,包括最后一个项目。为了避免这种情况,您可能会在
打印项目
中添加一些参数,指示它是否是列表中的最后一个项目。好的,谢谢我添加了
write(1),\r“,1);
在循环结束时修复它。