我正在尝试使用write
使用C中的终端列大小格式化文件列表。我正在尝试将输出格式化为如下所示,不使用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;
}
答案 0 :(得分:2)
您打印列表的循环应如下所示:
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++;
}
对于每一行,您跳过了一个项目,因为您只打印了一个'\n'
而不是该项目。输出中缺少“ft_env_utils.o”。
您忘记将剩余列数减少填充字节数。
这应该可以修复不正确的列宽。如果还希望逐列而不是逐行打印,则需要进行一些额外的排序。