• 検索結果がありません。

slide4.pptx

N/A
N/A
Protected

Academic year: 2021

シェア "slide4.pptx"

Copied!
22
0
0

読み込み中.... (全文を見る)

全文

(1)

ソフトウェア工学入門

第4回 ライブラリ関数

(2)

ライブラリ関数 stdio

stdio : 標準入出力ライブラリ

カーネルレベルのストリームにAPIを追加し、インタフェースを提供する カーネル プログラム

stdio

read(2) バッファ BUFSIZ write(2) fd BUFSIZごと 小さい単位 バッファ : 一時的にデータを保存しておく場所のこと バッファリング : バッファを経由してデータをやり取りすること バイト単位の遅いシステムコールより、素早く読み書きができる

(3)

FILE型の正体

FILE型 : ストリームを表現するために使用される型

FILE型の中にはファイルディスクリプタとstdioバッファ情報が入っている ファイルディスクリプタ 正式名称 stdioでの変数名 意味 0 STDIN_FILENO stdin 標準入力 1 STDOUT_FILENO stdout 標準出力 2 STDERR_FILENO stderr 標準エラー出力

(4)

fopen

fopen : stdioにおいてシステムコール open() に相当するAPI

#include <stdio.h>

FILE *fopen ( const char *path , const char *mode ) ;

ファイルをパス指定するとファイルに繋がるストリームを作り、FILE型へのポインタを返す 第二引数のmodeはストリームの性質を示す 値 mode 意味 “r” O_RDONLY 読み込み専用 “w” O_WRONLY_CREATEIO_TRUNC 書き込み専用 “a” O_WRONLY_CREATEIO_APPEND 追加書き込み専用 “r+” O_RDWR 読み書き両用 “w+” O_RDWRIO_CREATEIO_TRUNC 読み書き両用 “a+” O_RDWRIO_CREATEIO_APPEND 読み書き両用

(5)

fclose

fclose : stdioにおいてシステムコール close() に相当するAPI

#include <stdio.h>

int fclose ( FILE *stream ) ;

(6)

fgetc() と  fputc()

#include <stdio.h>

Int fgetc (FILE *stream );

Int fputc ( int c , FILE *stream );

バイト単位の入出力

API

fgetc( ) : 引数のstreamから1バイト読み込んで、バイト数を返す       ストリームが終了するとEOFを返す

(7)

getchar()とputchar

#include <stdio.h> Int getchar (void); Int putchar ( int c );

入力元と出力先が固定されているバイト単位の入出力

API

getchar( ) : fgetc( stdin) と同じ意味

       つまり、標準入力から1バイト読み込んで、バイト数を返す putchar( ) : fputc(c , stdout) と同じ意味

(8)

stdio版cat ①

#include <stdio.h> #include <stdlib.h> int

main(int argc, char *argv[]) {

int i;

for (i = 1; i < argc; i++) { FILE *f; int c; f = fopen(argv[i], "r"); if (!f) { perror(argv[i]); exit(1); } 次のプログラムをcat2.c という名前で作成し、保存してください

(9)

stdio版cat ②

while ((c = fgetc(f)) != EOF) { if (putchar(c) < 0) exit(1); } fclose(f); } exit(0); } 次のプログラムをcat2.c という名前で作成し、保存してください ビルドして、実行してみましょう >gcc -o cat2 cat2.c >ls

(10)

文字列処理 ① ルール

文字列(バイト列)の末尾に \n を付けることで1行を意味する

Hello World! \n もじもじもじもじもじ \n Gooooooooooooogle \n

例文 文字列 行の列

Hello World! \n

もじもじもじもじもじ \n

Gooooooooooooogle \n

(11)

文字列処理 ② fgets()

#include <stdio.h>

char *fgets ( char *buf , int size , FILE *stream );

文字列の行単位の入力

API

fgets : ストリーム stream から1行読み込んで、第1引数のbufに格納する      この際、最大 size-1バイトまでしか読み込まない

     正常に読み込めば buf を返す

(12)

文字列処理 ③ fputs()

#include <stdio.h>

int fputs ( const char *buf , FILE *stream );

文字列の行単位の出力

API

fputs : 文字列 buf をstream に書き込む      正常に読み込めば 0 を返す

(13)

文字列処理 ④ printf()とfprintf()

#include <stdio.h>

int printf ( const char *fmt , . . . );

int fprintf ( FILE *stream , const char *fmt , . . . );

文字列の出力

API

printf : 引数 fmt で指定した体裁に従って、後続の文字列を標準出力する fprintf :引数 fmt で指定した体裁に従って、後続の文字列をstreamに出力する printf は便利なため多用されるが、バッファオーバーフローの原因になる バッファオーバーフロー : バッファをはみ出してメモリを使ってしまうこと       データが破壊されるなどの問題を生じる

(14)

固定長入出力

Stdio経由で行う固定長バイト列の入出力

#include <stdio.h>

size_t fread ( void *buf , size_t size , size_t nmemb , FILE *stream ) ;

size_t fwrite (const void *buf , size_t size , size_t nmemb , FILE *stream ); fread : stream から size × nmemb バイトを読み込み、buf に格納する

     読み込みに成功すれば nmemb を返す      失敗すると nmemb より小さい値を返す

fwrite : size × nmemb 分のバイト列をbuf からstreamに書き込む       読み込みに成功すれば nmembを返す

      失敗すると nmemb より小さい値を返す

read()やwrite()はシステムコールだが、fread()とfwrite()はライブラリ関数

(15)

ファイルオフセット操作

ファイルオフセット操作のAPI

#include <stdio.h>

int fseek ( FILE *stream , long offset , int whence ) ; long ftell (FILE *stream );

void rewind (FILE *stream );

lseek()はシステムコールだが、fseek()はライブラリ関数

システムコールはUNIXでしか使えないが、ライブラリ関数はC言語で使える

fseek : stream のファイルオフセットをwhence と offset で示される位置に移動する

ftell : stream のファイルオフセットの位置を返す

rewind : stream のファイルオフセットの位置を先頭に戻す

(16)

ラッパー

カーネル プロセス ストリームA ストリームB ストリームC 0 1 2 1 ファイルディスクリプタ バッファ ストリーム

FILE

FILE型 : ストリームを表現するために使用される型

ラッパー : APIで覆って機能を追加すること

FILE

 はファイルディスクリプタのラッパーである

追加機能

stdio

(17)

ファイルディスクリプタとFILE操作

ファイルディスクリプタとFILE操作のAPI

#include <stdio.h>

int fileno ( FILE *stream ) ;

FILE *fdopen ( int fd , const char *mode );

fileno : stream がラップしているファイルディスクリプタの値を返す fdopen :ファイルディスクリプタ fd をラップする FILE型の値を新しく作成し、ポインタを返す 第二引数のmodeはストリームの性質を示す 値 mode 意味 “r” O_RDONLY 読み込み専用 “w” O_WRONLY_CREATEIO_TRUNC 書き込み専用 “a” O_WRONLY_CREATEIO_APPEND 追加書き込み専用 “r+” O_RDWR 読み書き両用 “w+” O_RDWRIO_CREATEIO_TRUNC 読み書き両用 “a+” O_RDWRIO_CREATEIO_APPEND 読み書き両用

(18)

stdio動作 演習 ①

>strace ./hello > /dev/null

execve("./hello", ["./hello"], [/* 56 vars */]) = 0 uname({sys="Linux", node="cl0028", ...}) = 0

brk(0) = 0x804955c

old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE| MAP_ANONYMOUS, -1, 0) = 0x40015000

open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/local/lib/i686/mmx/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)

stat64("/usr/local/lib/i686/mmx", 0xbfffee64) = -1 ENOENT (No such file or directory)

open("/usr/local/lib/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)

………..

straceコマンドを使って、以前作成したhelloの動作を見てみましょう

(19)

stdio動作 演習 ②

以前作ったcatを使って、システムコールread, write, open, close の動作を見てみましょう

2048バイト単位のreadが1回、102バイト単位のwriteが1回行われています 102×2=204バイトの転送が行われています

>strace -e trace=open,read,write,close ./cat hello.c > /dev/null ……….. close(3) = 0 open("/lib/i686/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\\\1"..., 512) = 512close(3) = 0 open("hello.c", O_RDONLY) = 3

read(3, "#include <stdio.h>\n\nint\nmain(int"..., 2048) = 102 write(1, "#include <stdio.h>\n\nint\nmain(int"..., 102) = 102 read(3, "", 2048) = 0

(20)

stdio動作 演習 ③

以前作ったcat2を使って、システムコールread, write, open, close の動作を見てみましょう

1024バイト単位のreadが1回、102バイト単位のwriteが1回行われています 102×2=204バイトの転送が行われています

メモリが1024バイト節約されているということですね → バッファリング効果

>strace -e trace=open,read,write,close ./cat2 hello.c > /dev/null ………. open("/etc/ld.so.cache", O_RDONLY) = 3 close(3) = 0 open("/lib/i686/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\\\1"..., 512) = 512close(3) = 0 open("hello.c", O_RDONLY) = 3

read(3, "#include <stdio.h>\n\nint\nmain(int"..., 1024) = 102 read(3, "", 1024) = 0

close(3) = 0

(21)

第一回個別試験告知

日時: 5月14日(木) 8:30~10:00

場所: S14生      情報棟5階AV実習室

     S10,S11,S12,S13生  大学院棟4階計算機実験室

当日スケジュール

8:40 答案配布

9:50 答案回収(出席確認のため)

10:00までにメールにてプログラムを送付

※ 他人との相談は厳禁です。

(22)

cat2.cの場合、次のように実行すると何も起こらない >./a.out > 課題の場合、次のように実行すると標準入力を受け付ける >./a.out 5    ← 標準入力 5 3    ← 標準入力 3 2    ← 標準入力 2

本日の課題

講義で作成したcat2.cを改良し、コマンドライン引数でファイル名が渡されなかったら、

標準入力を読み込むプログラムを作成しなさい

このようなプログラムを作成してください

参照

関連したドキュメント

子どもが、例えば、あるものを作りたい、という願いを形成し実現しようとする。子どもは、そ

えて リア 会を設 したのです そして、 リア で 会を開 して、そこに 者を 込 ような仕 けをしました そして 会を必 開 して、オブザーバーにも必 の けをし ます

ダウンロードしたファイルを 解凍して自動作成ツール (StartPro2018.exe) を起動します。.

ウェブサイトは、常に新しくて魅力的な情報を発信する必要があります。今回制作した「maru 

原則としてメール等にて,理由を明 記した上で返却いたします。内容を ご確認の上,再申込をお願いいた

 本資料作成データは、 平成24年上半期の輸出「確報値」、輸入「9桁速報値」を使用

 本資料作成データは、 平成26年上半期の輸出「確報値」、輸入「9桁速報値」を使用

 本資料作成データは、 平成29年上半期の輸出「確報値」、輸入「9桁速報値」を使用