2016-12-30 10 views
1

writeを使用して、CのTerminal columnsのサイズを使用してファイルのリストを書式化しようとしています。 printfまたはその他の書式設定機能を使用せずに、次のように出力を書式設定しようとしています。 enter image description here端末の列をCで書式化した出力

これは私が enter image description here

を得ていることは、ここに私のコードのリストを印刷するあなたのループは次のようになります

#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; 
} 

答えて

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'を印刷しただけで1つの項目をスキップしました。 "ft_env_utils.o"が出力にありません。 残りの列数を、パディングバイト数で減らすのを忘れました。

誤った列幅が修正されるはずです。行単位ではなく列単位で印刷することも望ましい場合は、いくつかの並べ替えが必要になります。

+0

最後の項目は余分なスペースを表示し、 '\ n'を' \ r'に変更しました。 – julekgwa

+0

はい、最後のものを含むすべての項目のパディングスペースを印刷します。これを避けるには、それがリストの最後の項目であるかどうかを示す 'print_item'にいくつかのパラメータを追加してください。 – Gerhardh

+0

OK、私は 'write(1、" \ r "、1);をループの最後に追加して修正しました。 – julekgwa

関連する問題