2012-02-11 9 views
2

私はこのコードがうまくいかない理由を理解するのに苦労しています。私はI/O操作の基礎を学んでおり、標準入力から与えられたものを 'log.txt'ファイルに書き込むCプログラムを考え出す必要があり、 'stop'という単語が入力されると、プログラムは停止する必要があります。ファイルにI/Oが書き込む問題

だから私のコードは次のとおりです。

#include "main.h" 
#define SIZE 1024 

int main(int argc, char *argv[]) 
{ 
    int fd; 
    int readBytes; 
    int writBytes; 
    char *buffer; 

    if ((fd = open("log.txt", O_WRONLY|O_APPEND)) < 0) 
    { 
     perror("open"); 
    } 

    buffer = (char *) calloc (SIZE, sizeof(char)); 
    while ((readBytes = read(0, buffer, SIZE) < SIZE)&&(strncmp(buffer, "stop", 4) != 0)); 

    if ((writBytes = write(fd, buffer, SIZE)) < 0) 
    { 
     perror("write"); 
    } 

    if ((close(fd)) < 0) 
    { 
     perror("close"); 
    } 
} 

私が入力した場合:

this is just a text 
this is more text 
and text again 
stop 

this is just a text 
stop 

を私が文を超えて入力した場合、出力は

stop 
is just a text 

です

これは、ログに記録されているものです。

stop 
ext again 
xt 
t 

そしてその上に、私はvimのからのlog.txtファイルまたは私が見ることができるだけで、テキストエディタ「\ 00年代を編集しようとした場合。 \ 00は、利用可能な1024バイトから空のまま残っているすべてのバイトを表していると思いますか?それをどうやって防ぐことができますか?

答えて

2

あなたは

readBytes = read(0, buffer, SIZE) < SIZE) 

を期待しているように何とかバッファで物事を蓄積することになります。それはしません。すべての後続のreadは、バッファの先頭に読み込んだ内容を置き換え、前のreadの内容を上書きします。

あなたはwhileブロックであなたのwriteを配置する必要があります - そうでなければ、ごみを書くつもり、すべての読み取りのための1個の書き込み、およびあなたread限りのみwrite(前回のリードからcallocおよび/または残り物からゼロ)あなたのログファイルに。

あなたのテクニックは、ほとんどの場合、ラインバッファリングされた入力ストリームでは機能しますが、ファイルやパイプからリダイレクトした場合、期待どおりに動作しません。書式設定された入力関数(scanf、またはfgetsの実装の場合はgetlineなど)を使用する必要があります。

+0

私はそれがある種の話題ではないことを知っていますが、これらのオープン/リード/ライト機能は正確に何であり、どこで定義されていますか?彼らは彼らのフリードe.t.cに似ているようです。カウンターパート。 – Lefteris

+0

'read'と' write'は ''の ''、 'open'にあります。 manページを見るために 'man 2 open' - セクション2:システムコール。 – Mat

+0

ありがとうマットは今見ています – Lefteris

関連する問題