C言語のread関数についての疑問

このQ&Aのポイント
  • ファイルディスクリプタを使用するC言語のread関数についての疑問です。
  • open関数で得られたファイルディスクリプタをread関数に渡す方法が分かりません。
  • 具体的なコード例を挙げながら質問しています。
回答を見る
  • ベストアンサー

C言語のread関数に関するファイルディスクリプタ

C言語のread関数に関するファイルディスクリプタについて質問です。 open関数から得られたファイルディスクリプタを、一般的には変数(例:fd)に代入して、fdをread関数や、write関数の第1引数として用いるんですが、ファイルディスクリプタは数値のはずなので、それを引数として用いてもどうやってそこからパス情報を得ることが出きるのかが分かりません。 例えば以下のような場合です。 ****** 省略 fd = open("/home/XXX/YYY", O_RDONLY); read(fd, buf, 10); 省略 ****** 誰か詳しい方がおりましたら、どうかご教授よろしくお願い致します。

noname#183277
noname#183277

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.4

>open関数からの返り値はアドレス的な意味をもつということでしょうか 配列の添字であり、それ以上でも以下でもありません。 配列の添字は「アドレス的な意味を持つ」とあなたが思うのであればそうです。 >というのも、課題でopen,read関数等を自力で作成せよ、というような課題が出されたので、どうにかして作成したいので・・・ Unix/Linuxでは、openやreadはシステムコール(言語から扱える一番下位レベルの関数)なので、openやreadを呼び出すことなしに同じ機能の関数を作ることは不可能です。 Windowsであれば、Win32APIなどがシステムコールに当たると思いますので、それらを使えばopen/read相当を自作するのは可能でしょう。 システムコールを呼び出すのに必要な情報を全部持ったような構造体の配列を作ればいいわけです。その添字がファイルディスクリプタです。

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

その他の回答 (6)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.7

大雑把に言うと、OS内部でopenしたデバイス(ファイルの形式を取っていても「ファイル」とは似ても似つかない場合もあるのがミソ)とディスクリプタ番号の符合を行っているだけです。

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

そもそもファイルディスクリプタから「パス情報を得る」というのが何を意味するのかわかりません. 実際にデータを読み書きするときに「パス情報」が必要とは思えないよね?

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

  • wormhole
  • ベストアンサー率28% (1619/5654)
回答No.5

ひとまずプラットホームはなんでしょうか? 「WindowsのWIN32APIを使ってopen,read,write,close互換ライブラリを作ろう」 とかなら意味わかりますけど、 unixやlinuxだとopen,read,write,closeはシステムコールなので open,read,write,close互換ライブラリを作ろうとしたところで 結局システムコールのopen,read,write,close使うことになってしまいますが。

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.3

open(), read() を「関数」と言ってますが、システムコールですよ? システムコールを自作したいと言ってる?

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

noname#183277
質問者

補足

あまり知識がないもので、すいません(^^;)。 これは自作できるようなものではないのでしょうか

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

おおざっぱに動作を書けば次のようになります。 openでファイル等と番号を関連付ける。OSでその関係を覚えておく → read等で番号を指定する →OSでその番号に関連付けてあるファイル等にアクセスする パス情報っていうのがどこから出てきたのか、よくわかりません

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

noname#183277
質問者

補足

回答ありがとうございます。 パス情報は、絶対パスや相対パスをここでは言っています。(上の例では/home/XXX/YYYです)説明不足ですいません(^^;)。 下の方の補足にも記述したんですが、もしoepn関数やread関数を自力で作成するときは、どのようにしたらいいのでしょうか

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

ちょっと不正確ですがわかりやすく説明するなら、 ファイル入出力ライブラリはその内部でファイル入出力に必要な情報を管理する配列を持っています。 open関数はその管理配列の中で使用されていない要素を選び出し、その配列要素の中に必要な情報を格納したあと、その要素番号をファイルディスクリプタとして返します。 read関数では、受け取ったfdをもとにその管理用配列にアクセスすれば、必要な情報を取得できる、という流れになります。

noname#183277
質問者

お礼

遅くなってしまい申し訳ありません. 回答して頂きありがとうございました.

noname#183277
質問者

補足

回答ありがとうございます。 open関数からの返り値はアドレス的な意味をもつということでしょうか そうすると、もし自作のopen,read関数を作成するときには、どのようにしたらいいのでしょうか というのも、課題でopen,read関数等を自力で作成せよ、というような課題が出されたので、どうにかして作成したいので・・・

関連するQ&A

  • 関数と変数と定数と式をまとめて [C言語]

    はじめまして。私はC言語初心者です。 C言語では、関数の引数や変数への代入や配列の添え字などに、変数や定数や、式や関数の値を利用できるじゃないですか。私は今C言語について勉強したことをファイルにまとめていっているのですが、上記のようなことを説明するたびに「関数と変数と定数と式」と書くと長ったらしくなってしまいます。そこで、これらをまとめていう言葉があったら教えて欲しいのです。 回答よろしくお願いします。

  • C言語の関数の実引数と仮引数の名前について

     C言語で関数を使う場合、実引数と仮引数の名前(変数名)は、変えなければならないのでしょうか、同じでもいいのでしょうか。C言語のルールでは、どうなっているのでしょうか。よろしくお願い致します。

  • 構造体をディスクからロードして複数バッファリングさせる

    構造体をディスクからロードして複数バッファリングさせておくようなプログラムを組みたいと思い、 C言語で下のようなコードを記述しました。 ※質問にあたり最小限の記述にしています。 #define SIZE (sizeof(struct hoge)) #define NUM 16 char buf[SIZE*NUM]; fd=open(file_name,O_RDONLY); read(fd,buf,SIZE*NUM); 上のような記述(read)をして構造体(hoge)を16個分確保できてしまいました。 ここで疑問に当たりました。 (1) read(fd,buf,SIZE); (2) read(fd,buf,SIZE*NUM); 個人的には(1)と書いても(2)のように書いて、fdが指すポインタから、SIZE分読み込んだ時点で、ファイルの末尾に達するので読み込みが終わると思っていました。 SIZE*NUM分読めたことに納得がいきません。 末尾にきたらファイルの先頭に戻っているのでしょうか? readのmanを読んでも間違いないと思えるのですが。。 お分かりの方いらっしゃいましたらぜひぜひ教えてくださいませ。

  • C言語で自作したcpコマンドが上手く動作しません

    当方、プログラミングを勉強中の学生です。 先日、ファイル入出力関数を用いてcpコマンドを自作しました。 一応、コンパイルは通るのですが、コピーしたファイルを開くことができません。 そのファイルのパーミッションを確認してみたところ 「----------」となっており、読み書き実行すべて不可となっていました。 ソースは以下の通りなのですが、何が問題でしょうか。 回答よろしくお願い致します。 #include<stdio.h> #include<fcntl.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #define SIZE 8192 int main(int argc, char *argv[]) { int fd1, fd2; char buf[SIZE]; if ( argc != 3 ){ char err_message[] = "ファイル名を指定して下さい。\n"; write(2, err_message, strlen(err_message)); return 1; } argv[0] = "mycopy"; fd1 = open(argv[1], O_RDONLY); fd2 = open(argv[2], O_WRONLY | O_CREAT); if (fd1 < 0 || fd2 < 0) { char err_message[] = "ファイルをオープンできません。"; write(2, err_message, strlen(err_message)); write(2, strerror(errno), strlen(strerror(errno))); write(2, "\n", 1); return 1; } while(1) { if (read(fd1, buf, SIZE) == 0) { break; } else if (read(fd1, buf, SIZE) > 0) { write(fd2, buf, SIZE); } else { char err_message[] = "エラーが発生しました。"; write(2, err_message, strlen(err_message)); write(2, strerror(errno), strlen(strerror(errno))); write(2, "\n", 1); return 1; } } close(fd1); close(fd2); return 0; }

  • 関数スコープの変更の仕方について

    こんにちは。いつも勉強させていただいております。 VB2005始めて間もない初心者なので分かりにくい表現が多々あるかと思いますが よろしくお願いいたします。 現在2つのプロジェクトを作っていて、どちらもxxx.dllというファイルを参照しています。 やりたいことは、xxx.dll内でグローバル変数として宣言しているyyy変数の関数スコープを動的に変更したいと思っております。 プロジェクト1ではyyy変数の関数スコープをPrivate プロジェクト2ではyyy変数の関数スコープをPublic なお、このxxx.dllは他にも色々と使われており、基本はPrivateのままにしておきたいので、 最初からxxx.dllのグローバル変数のスコープをPublicにすれば良いということはできません。 特定のプロジェクトから呼び出されたときだけPublicにすることは可能でしょうか? どうぞよろしくお願いいたします。

  • シリアル通信でのread関数の戻り値

    オムロン製PLCと上位コンピュータをRS232Cで接続し、FINSコマンドを用いてシリアル通信をしようとしています。 現在作っているプログラムの流れは、 ・シリアルポート"/dev/ttyS2"のオープン   comm_fd = open("/dev/ttyS2", O_RDWR | O_NOCTTY); ・通信設定   termios構造体を設定 ・コマンドフレーム(COMMAND)を作成し、ポートに書き込む   write(comm_fd, &COMMAND, strlen(COMMAND)); ・PLCからのレスポンスを読み出す   read(comm_fd, &RESPONSE, 256); のようにしているのですが、read関数が実行されたままになってしまいます。(エラーコードも返ってこない状態です) readの戻り値が-1ならポートにアクセスできていないとわかるのですが… ためしにcomm_fdと違う値をread関数に入れてみたところ(read(6, &RESPONSE, 256)、戻り値は-1となりました。 これはどういう状態になってしまっているのでしょうか? わかりにくい質問で申し訳ありません。

  • アセンブリ言語とC言語について。

    以下のURLで、 https://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al … No.14のC 言語の write の仕様そのもので、第一引数はファイルディスクリプタですね。 (ファイルディスクリプタについては御自身で調べてみてください) 固定値として定義されているのは、標準ストリーム ファイルの  0 … 標準入力 (write では使われない)  1 … 標準出力  2 … 標準エラー出力 です。(3 以降は各プロセスでオープンされたファイルやソケットやデバイスを 指しており、固定値ではなくプロセス毎に異なる値となります。) 括弧の所がよくわかりません。教えていただけると幸いです。すみません。

  • C言語→C#に変換

    C言語→C#に変換 C言語からC#に変換したいのですが、わからないところがあります。 コマンドライン引数からファイル名とキーワードを入力して、キーワードがある行をアウトプットファイルに書き込むという処理です。 C言語のソースは、 main(int argc,char *argv[]){ FILE *fp; FILE *fpp; int i; char KEYWORD[256]; char buf[256]; //(1)アウトプットファイルのオープン fpp=fopen("output.txt","w"); for(i=1;i<argc-1;i++){ if(strcmp(argv[i],"-a")==0){ //(2)入力ファイルのオープン if((fp=fopen(argv[i],"r"))==NULL){ printf("open error!\n"); exit(1); } } //(3)キーワードの代入 if(strcmp(argv[i],"-b")==0){ strcpy(KEYWORD,argv[i]); } } //(4)一行読み込む while(fgets(buf,sizeof(buf),fp)!=NULL){ //(5)キーワードの条件で文字列抽出 if(strstr(buf,KEYWORD)!=NULL){ //(6)アウトプットファイルに出力 fprintf(fpp,"%s",buf); } } //ファイルクローズ fclose(fp); fclose(fpp); } です。 (3)キーワードの代入と、(5)文字列抽出の部分がネットなどで調べてもよくわかりません。 分かる方いらっしゃいましたら教えていただけると幸いです。 宜しくお願いします。 .

  • 【C言語】引数にファイルパスを送りたい

    DLLで外部のファイルサイズを得る関数を作っています。 C言語は書きながら覚えていこうとしているのですが、 どうしても分からない点がありました。 ソースをここに正しく書ける自信がないので日本語を含めて大体で書きます。 いろいろなサイトのコピペです。 double __stdcall filesize(){ HANDLE hFile; DWORD size; hFile = CreateFile( _T(絶対パス, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); size = GetFileSize( hFile, NULL ); CloseHandle( hFile ); return(size); } このような感じで書いていて最後にretuenでファイルサイズを正しく得ることができました。 この絶対パスは環境によって変わるので引数にしようと考えました。 そしてfilesize()の中にどのように記述すればいいかで躓いています。 filesize(絶対パス){ char pass[] = "絶対パス"; hFile = CreateFile( _T(pass, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); こんな感じで書ければいいのですがC言語はポインタや文字列の扱いが難しいですね。 初歩的なことで申し訳ありませんがよろしくお願いします。

  • C言語のポインタによる関数の引数の書き方について教えてください。

    C言語を今勉強中の大学生です。 一気に複数の値をmainに返せる、参照による呼び出しによる関数の引数の書き方で困っています。配列を自作関数に引き渡したいのですが、どう書けばいいのでしょうか。 下の3つは、それぞれ(1)mainからの呼び出し、(2)自作関数での引数の引き受け、です。どこをどう変えたらエラーが出なくなるのか、分かる方、お願いいたします! (1)school(&m,h); (2)void school(int *m, float *h){ ※ちなみに変数は int m,float h[10][10]

専門家に質問してみよう