第 3 回ネットワークプログラミング
DESCRIPTION
第 3 回ネットワークプログラミング. 中村 修. 今日のお題. ディスクリプタ file I/O 練習問題1: cat –n を作ってみよう ポインタ ポインタと文字列 練習問題2:ファイルの中身をひっくり返してみよう 引数 argc,argv 練習問題3: 引数を出力しよう -------- (休憩) ----------------- 実習 cat –n –r file1 file2 file3 …… を作ろう. ファイルディスクリプタ. プロセスが外の世界と通信するためのデータの入り口 全ての通信は、必ずファイルディスクリプタを通じて行われる - PowerPoint PPT PresentationTRANSCRIPT
第 3回ネットワークプログラミング
中村 修
今日のお題 ディスクリプタ
file I/O 練習問題1: cat –n を作ってみよう
ポインタ ポインタと文字列 練習問題2:ファイルの中身をひっくり返してみよ
う 引数
argc,argv 練習問題3: 引数を出力しよう -------- (休憩) -----------------
実習 cat –n –r file1 file2 file3 …… を作ろう
ファイルディスクリプタプロセスが外の世界と通信するためのデータの入り口全ての通信は、必ずファイルディスクリプタを通じて行われる
(予約済)0: 標準入力(キーボード)
1: 標準出力(モニタ) 2: 標準エラー出力(モニタ)
入出力関数 :システムコール open read write close
次のページから例あり
open()システムコール int open(char *path, int flags, …);
返り値がファイルディスクリプタ 引数は基本的に 3 つ
char *path 開くファイルのパス名が保存されている文字配列 ( への
ポインタ ) int flags
ファイルを開くときにどのような状態で開くかを決める 読み込みだけ (O_RDONLY) 書き込みだけ (O_WRONLY) 読み書き両方 (O_RDWR) 追加 (append) (O_APPEND) 新規作成 (O_CREAT) ブロックしない (O_NONBLOCK)
3 番目は便宜的に 0
read()システムコール
int read(int d, void *buf, size t nbytes) 引数
int d: ファイルディスクリプタ void *buf: 読み込んだデータを保存するための配列 ( バッファ ) size_t nbytes: 1 回の read() で読める最大バイト数 ( バッファの
大きさ ) 返り値
int: 実際に読み込んだバイト数 0 より大きい: 読み込み成功 0 : ファイルの最後 (EOF) に到達 0 より小さい: エラー
write()システムコール int write(int d, void *buf,size t nbytes)
引数 int d: ファイルディスクリプタ void *buf: 書き込むデータを保存している配列・ポインタ
( バッファ ) size_t nbytes: 1 回の write() で書き込むバイト数 ( 書き込む
データの大きさ )
返り値 int: 実際に書き込んだバイト数
0 より大きい: 書き込み成功 0 より小さい: エラー
close()システムコール int close(int fd);
引数 int fd: ファイルディスクリプタ
返り値 0: 成功 0 より小さい: エラー 通常はあまりチェックしない
open()/read()/write()/close()の例#include <fcntl.h>#include <sys/types.h>#include <sys/uio.h>#include <unistd.h>#define BUFSIZE 1024
int main(){ char buf[BUFSIZE]; int fd; int nbyte; fd = open(“test.txt”, O_RDONLY, 0); while((nbyte = read(fd, buf, BUFSIZE)) > 0) { write(1, buf, nbyte); } close(fd); exit(0);}
ファイルを扱う関数 fopen(char *filename, char *mode)
r,w,a,r+,w+,a+ fgets(cahr *s,int length,FILE *fd) fgetc(FILE *fd) fclose(FILE *fd)
次のページに練習問題あり
これらの関数を使うと#include <stdio.h>int main(){ FILE *fp; char buf[1024]; int c; fp = fopen(“sample.txt”,"r");
while((fgets(buf, sizeof(buf),fp)) != NULL){ fputs(buf,stdout); } fclose(fp); exit(0);}
練習問題 1
-n オプションを指定した cat コマンドのように、左端に行番号を出力するようなプログラム catn.c を作成するsample.txt を読み込んで 行番号を付けて出力。
sample.txt /home/kaizaki/osamuNP/3/sample.txt
次のページから「ポインタ」解説
ポインタ"T""h""i""s"" ""i""s"" ""t""e""s""t"
メモリ空間100
101
102
103
104
105
106
107
108
109
110
111
アドレス
"."112
113
char string[] = "This is test.";
100200
….201
NULL
char *s = string;
string[]
"で括った文字列はどこかに格納されている
ポインタ変数: メモリアドレスを格納している 変数型: ポインタが示すメモリにどの型で格納さ れているかを示す cf char *s; 文字 ( 列 ) が入っている変数 のアドレスが入る変数
文字列とポインタ
文字列は配列で管理されている char mystr[8] = “hello”;
char *mystr = “hello”;
h e l l o \0
h e l l o \0
*mystrmystr[0]
*(mystr+1)mystr[1]
*(mystr+2)mystr[2]
*(mystr+3)mystr[3]
*(mystr+4)mystr[4]
mystr = “hello”mystr + 1 = “ello”mystr + 2 = “llo”mystr + 3 = “lo”mystr + 4 = “o”
文字配列と文字定数とポインタ
文字配列 char str1[8] = “hello”;8つの文字変数からなるstr1という配列を用意
ポインタ char *ptr = “hello”;
str1
h e l l o \0“hello” どこかに存在する
h e l l o \0配列に対して「どこかに存在している」” hello”の内容をコピー (初期化 )
文字変数を指すポインタ型変数 ptr を用意
ポインタ変数に対して「どこかに存在している」”hello”のアドレスをコピー (初期化 )
0xff0120
文字列定数 宣言時にどこかに存在する (無名配列 )
str1
ptr
ptr
ポインタが役に立つ時は? ポインタの利用例
動的に割り当てた配列 (malloc() など ) 複数ある類似の変数への汎用なアクセス 関数引数の ( 擬似的な ) 参照渡し (call by reference) あらゆる種類のデータ構造を動的に割り付ける
cf ツリー構造、リンクリスト 配列や効率のよい参照渡しのコピー
関数引数の場合
次のページに練習問題あり
練習問題 2
sample.txt ファイルの内容をひっくり返して、 anagram.txt という名前のファイルを作成する。
abcdefghijkl : :
fedcbalkjihg : :
コマンドライン引数: argc,argvコマンドの引数を用いるには ?
cat –n filecat file1 file2 file3
コマンドライン引数の利用法 main( int argc, char **argv) main( int argc, char *argv[])
argc には引数の数 argv[0] にはコマンド名 argv[1] には 1 番目の引数 argv[2] には 2 番目の引数
練習問題3 argc,argv を用いて引数を全て出力する。 実行例 / 出力例
%./a.out 123 456 789
arg[0]: ./a.out
arg[1]: 123
arg[2]: 456
arg[3]: 789
練習問題 3の回答#include<stdio.h>
int main(int argc, char *argv[]){
int i; for(i = 0; i < argc; i++){ printf("arg[%d]: %s\n", i, argv[i]); }
}
実習 今日作成した、
cat –n cat –r (中身をひっくり返す ) 引数を出力する関数
を参考に、以下の書式を満たす catを作成する cat –r cat –n cat file1 file2 file3 複数のオプションを同時に満たす機能を実現できたらボーナス得点。
実習ヒント -r –n などは 2 通りでチェックできる
if(*argv[i] == ‘-’ && *(argv[i]+1) == ‘r’ ) if(argv[i][0] == ‘-’ && argv[i][1] == ‘r’)
fopen でファイルを開いたら、かならず fclose