read()によるファイルの読み込みで失敗する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Ohagi
記事: 31
登録日時: 3年前

read()によるファイルの読み込みで失敗する

#1

投稿記事 by Ohagi » 2年前

read()を使ってファイルから5バイトずつ読み込むようなサンプルプログラムを作成していたのですが
ファイルの終端になっても-1を返してくれないようで悩んでいます。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
  int fd;
  char buff[10];
  
  if (argc < 2) {
    fprintf(stderr, "usage: *.exe filename\n");
    exit(EXIT_FAILURE);
  }

  if ((fd = open(argv[1], O_RDONLY)) == -1) {
    perror("open(): ");
    exit(EXIT_FAILURE);
  } else {
    while (read(fd, buff, 5) != -1) {
      printf("printf(): %s\n", buff);

      // check null character
      if (buff[5] == '\0') {
        puts("null character is ok.");
      } else {
        printf("buff[5] = %d\n", buff[5]);
      }
      
    }
    close(fd);
  }

  return 0;
}

コード:

printf(): Hello
ok
printf():  Worl
ok
printf(): d

rl
ok
printf(): d

rl
ok
(以下略)

ファイルの終端までディスクリプタを進めたら-1を返してくれると思うのですが
どうして同じ場所を何度も読み込んでいるのでしょうか。

またread()で代入した文字列は手動でナル文字を入れる必要があると
とあるサイトでは説明されているのですが、
ここでは何もしなくてもナル文字が入っているようなのですがどうしてでしょうか?
「buff[rc] = '\0';」でread()関数で読み込んだ配列の最後に'\0'を書き込む必要があります。 文字列の最後には'\0'が必要なためです。
これを行わないとprintf()関数などで文字列として表示できません。
http://www.orchid.co.jp/computer/cschool/CREF/read.html

かずま

Re: read()によるファイルの読み込みで失敗する

#2

投稿記事 by かずま » 2年前

Ohagi さんが書きました:ファイルの終端になっても-1を返してくれないようで悩んでいます。
read() は読み込んだ文字数を返します。
ファイルの終端では、読み込めないので、0 を返します。
-1 を 0 に変更してみてください。
Ohagi さんが書きました:またread()で代入した文字列は手動でナル文字を入れる必要があると
とあるサイトでは説明されているのですが、
ここでは何もしなくてもナル文字が入っているようなのですがどうしてでしょうか?
char buf[10]; で buf は未初期化ですが、
偶然 buf[5] が '\0' だったのでしょう。
char buf[10] = "012345678"; にしてみてください。
Ohagi さんが書きました:
「buff[rc] = '\0';」でread()関数で読み込んだ配列の最後に'\0'を書き込む必要があります。 文字列の最後には'\0'が必要なためです。
これを行わないとprintf()関数などで文字列として表示できません。
'\0' を入れる方法

コード:

    char buff[6];
    while ((n = read(fd, buff, 5)) != 0) {
        buff[n] = '\0';
        printf("[%s]\n", buff);
    }
'\0' を入れなくても printf は使えます。

コード:

    char buff[5];
    while ((n = read(fd, buff, 5)) != 0) {
        printf("[%.*s]\n", n, buff);
    }

Ohagi
記事: 31
登録日時: 3年前

Re: read()によるファイルの読み込みで失敗する

#3

投稿記事 by Ohagi » 2年前

かずまさん、返信ありがとうございます。

戻り値の-1はエラー時に戻る値で、ファイルの終端は0バイトの0だったんですね。
慣れない英語のmanページを見ていたのでミスリードしていました。

ナル文字の疑問も教えていただいたコードを試してみると
確かにread()ではナル文字が挿入されていないことが確認できました。
read()のあとにはナル文字を追加するように意識しようと思います。

ありがとうございました。

返信

“C言語何でも質問掲示板” へ戻る