2017-04-22 3 views
0

readstdinから読み込み、stdoutに読み取ったバイト数を渡して、ファイルを引数として渡します(teeコマンドを模倣しています)。しかし、私は実行すると:C read関数が要求よりも多くのバイトを読み取っています

echo AAAAAAAAAA | ./tee -a file 

私はあなたがreadが要求されたバッファサイズよりもはるかに大きい数を返していることがわかります

AAAAAAAAAA 
Â7þ­hý6þ­hý¥g¢c¾ 
@ERROR: failed to write whole buffer (140726359686392 != 2880) 

を取得します。 writeも要求以上に書き込みを行っていますが、readが返す数値は実行ごとに異なりますが、writesは入力のサイズに関係なく常に2880を返します。あなたがnum_readを読んだとき、あなたがBUFFER_SIZEバイトをwrtingされているので

#include <stdbool.h> 
#include <stdio.h> 
#include <stdlib.h> 

#include <fcntl.h> 
#include <stdarg.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#include <string.h> 

#define BUFFER_SIZE 64 

extern int optind; 

void exit_err(char *format, ...) 
{ 
    va_list args; 

    fflush(stdout); 

    va_start(args, format); 
    fprintf(stderr, format, args); 
    va_end(args); 

    fprintf(stderr, "\n"); 

    fflush(stderr); 
    exit(EXIT_FAILURE); 
} 

int main(int argc, char *argv[]) 
{ 
    if (argc < 2 || strncmp(argv[1], "--help", 6) == 0) 
     exit_err("USAGE: %s [-a] [OUTPUTFILE]", argv[0]); 

    bool append = false; 

    char opt; 
    while ((opt = getopt(argc, argv, "a")) != -1) { 
     switch (opt) 
     { 
      case 'a': 
       append = true; 
       break; 
      default: /* ? */ 
       exit_err("USAGE: %s [-a] [OUTPUTFILE]", argv[0]); 
     } 
    } 

    if (optind >= argc) { 
     exit_err("ERROR: expected argument after options"); 
     exit(EXIT_FAILURE); 
    } 

    int open_flags = O_WRONLY | O_CREAT; 
    if (append) 
     open_flags |= O_APPEND; 
    else 
     open_flags |= O_TRUNC; 

    mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP; 

    int num_output_files = argc - optind + 1; 
    int output_fd[num_output_files]; 
    output_fd[0] = STDOUT_FILENO; 

    int i; 
    for (i = 1; i < num_output_files; ++i, ++optind) { 
     output_fd[i] = open(argv[optind], open_flags, permissions); 
     if (output_fd[i] == -1) 
      exit_err("ERROR: failed to open %s", argv[optind]); 
    } 

    ssize_t num_read, num_written; 
    char buffer[BUFFER_SIZE]; 
    while ((num_read = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0) 
     for (i = 0; i < num_output_files; ++i) 
      if ((num_written = write(output_fd[i], buffer, BUFFER_SIZE)) != num_read) 
       exit_err("ERROR: failed to write whole buffer (%zd != %zd)", num_read, num_written); 

    if (num_read == -1) 
     exit_err("ERROR: failed to read from stdin"); 

    for (i = 0; i < num_output_files; ++i) 
     if (close(output_fd[i]) == -1) 
      exit_err("ERROR: failed to close file"); 

    exit(EXIT_SUCCESS); 
} 

答えて

2

:ここ

はコードです。

ちょうどまた、この

while ((num_read = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0) { 
    for (i = 0; i < num_output_files; ++i) { 
     if ((num_written = write(output_fd[i], buffer, num_read)) != num_read) { 
      exit_err("ERROR: failed to write whole buffer (%zd != %zd)", num_read, num_written); 
     } 
    } 
} 

、中括弧を使用して、インデントのあまりに多くのレベルを避けるようにそれを行う、この場合は読みにくかったです。

+0

Aaaaaaaaaaarg、どうすればこのことがわかりません... –

0

間違ったサイズの書き込みのほかに、va_listfprintfに渡しているため、間違ったサイズのメッセージが表示されることはありません。代わりにvfprintfに電話する必要があります。

関連する問題