2017-10-25 4 views
0

標準入力から文字列を求め、以前に書かれた文字列を標準エラーで書き込むプログラムを作成する必要があります。 は、これは私のプログラムです:read()関数内のリミットバッファ

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

int main() { 
    char *buffer = malloc(sizeof(char)*20); 
    int len = 0; 

    do { 
     len = read(STDIN_FILENO, buffer, 20); 
     if(len == -1) 
      write(STDERR_FILENO, "Error read\n", 10); 
     else 
      write(STDERR_FILENO, buffer, len); 
    } while(strncmp(buffer,"fine\n", 5)); 

    free(buffer); 
    return 0; 
} 

コード作品が、私はsatisfied..thereないよ一つの問題がある: バッファが20charですが、私は20以上の文字を挿入することができます...なぜ?どのように私はバッファを20文字に制限することができますか?

+0

__exactly__はどの要件ですか?文字ファイルの長さをかなり長い数字(例:4000)に制限することができます。これは、テキストファイルでは長い行の折れ線がほとんどないためです。私はまた、 'read'と' write'を使わず、 'fread'と' fwrite'、あるいは入力が行指向であれば 'fgets'を使うことを提案します。 –

+0

注: 'strlen(' "Error read \ n") 'は11ではなく10です。 – wildplasser

+0

20文字以上の"挿入 "(読み込み)はできないと思います。 'read'はあなたのバッファサイズで止まります。 –

答えて

0

コードは機能しますが、私は満足していません.1つの問題があります:バッファは20文字ですが、20文字以上挿入できます...なぜですか?

プログラムは20文字以上の入力を停止できないため、可能なことはの制限です。既に行われているbufferがオーバーフローしないようにしています - read()は要求されたバイト数を超えて読み取ることはできません。 read()コールがサイズ(20)を超えて読んでいるが、acutally read()は20文字しか読まず、残りは次の反復で読み取られるかのように、と表示されます。

入力の読み取りやバッファサイズの増加にどのような方法を使用しても、この「余分な入力」の問題は常に存在します。あなたの代わりに何ができるか がlenは20 buffer[19]ある場合\nでないかどうかを確認です:

else { 
     write(STDERR_FILENO, buffer, len); 
     /* Read out the left over chars. */ 
     if (len == 20 && buffer[19] != '\n') { 
      char c; 
      do { 
       read(STDIN_FILENO, &c, 1); /* left out the error checking */ 
      } while (c != '\n'); 
     } 

やバッファサイズを大きく、たとえば、だけにして512バイトとしているあなたの最初の20のバイトを見て

注:のエラーチェックをすべてread()write()と追加してください。

+0

あなたの最初の解決策を実装しましたが、いくつか質問があります。入力が(19文字+ \ n)以上かどうかを確認します。はいの場合、それは何を読みますか?(STDIN_FILENO、&c, 1);?私は..私がendlineコマンドを挿入しない場合、どうなりますか?何も問題はありませんが、理由は分かりません。 – Serus

+0

'read(STDIN_FILENO、&c, 1);')は1バイトを読み込みます(そして破棄されます)。改行を入力しないと、プログラムは入力を取得しませんすべて(また、[参照](https://www.gnu.org/software/libc/manual/html_node/Canonical-or-Not.html))。 – usr

0

バッファに十分なメモリを割り当てていません。 NUL終端文字を格納するには、常に1つ以上が必要です。また、NUL文字をreadで読み取った文字列の末尾に追加することを覚えておく必要があります。

エラーが発生した場合は、ループを終了する必要があります。

#define BUF_SIZE (20) 
int main() { 
    char *buffer = malloc(sizeof(char)*(BUF_SIZE+1)); 
    int len = 0; 

    do { 
     len = read(STDIN_FILENO, buffer, BUF_SIZE); 
     if(len == -1) { 
      write(STDERR_FILENO, "Error read\n", 10); 
      break; 
     } else { 
      buffer[len]='\0'; 
      write(STDERR_FILENO, buffer, len); 
     } 
    } while(strncmp(buffer,"fine\n", 5)); 

    free(buffer); 
    return 0; 
} 

あなたはおそらくも(strncmp(buffer,"fine\n", 5)readは喜んで一度に複数行に読みますと、あなたが入力の行を処理するために、文字列に読み取りを処理する必要があるだろうと仕事に行くされていないことがわかりますそれらがすべてバッファサイズに収まると仮定して)。

関連する問題