情報処理Ⅱ
情報処理Ⅱ
第12回
2011年1月17日(月)
13
31
2011年1月17日(月)
31
本日学ぶこと
本日学ぶこと
ファイル入出力,標準入力・標準出力
記憶域管理関数(mallocなど)
記憶域管理関数(mallocなど)
問題
問題
ファイルを入力にとり,先頭に行番号をつけて出力できる? 行列の積を,ファイルを介して読み書き・計算できる? W k 1 W k Wakayama University ./line 1:Wakayama 2:University ‐22 ‐16 14 8 ./matrix 5 4 3 2 ‐3 ‐2 ‐1 1 2 3 2 14 8 1 0 1 2 3フ イル補足
ファイル補足
Cでは,ファイルその他への入出力方法は文法で規定されて
いない 代わりに豊富なライブラリ(標準入出力ライブラリ)が
いない.代わりに豊富なライブラリ(標準入出力ライブラリ)が
規定されている.
ストリームは ファイルやコンソール(キーボード入力と画面
ストリ ムは,ファイルやコンソ ル(キ ボ ド入力と画面
表示)などを統一的に扱うためのものである.
テキストストリームとバイナリストリームに分けられる 前回と今 テキストストリームとバイナリストリームに分けられる.前回と今 回の授業では,テキストストリームを対象とする. 入出力の途中にナル文字('¥0')があっても問題なく処理でき 入出力の途中にナル文字( ¥0 )があっても問題なく処理でき なければならない. 3 リpp.455-456liline.c
仕様
コマンドライン引数(複数あればそれぞれ)をファイル名とみな コマンドライン引数(複数あればそれぞれ)をファイル名とみな して,そのまま出力していく.ただし行の先頭には行番号をつ ける. 考え方
fgetcfgetcを用いて1バイトずつ読み出す fgetcfgetcを用いて1バイトずつ読み出す. 「行の先頭」とは,「ファイルの先頭」か「改行文字('¥n')の直 後」のいずれか 後」のいずれか. 「今何行目を読んでいるか」を保存する変数line_countを用 意する. 意する. 4 line.c1文字ごとの読み出し(1)
1文字ごとの読み出し(1)
while ((c =
while ((c = fgetc
fgetc(
(fp
fp)) != EOF) {...}
)) != EOF) {...}
ファイルabc これがストリーム ファイルabc
'a'
'b'
'c'
'¥n' プログラムの 内部状態fp
FILE
オブジェ
fp
オブジェ
クト
'¥0'がない点に注意c = ???
¥0 がない点に注意 (文字列ではない) 51文字ごとの読み出し(2)
1文字ごとの読み出し(2)
while ((c =
while ((c = fgetc
fgetc(
(fp
fp)) != EOF) {...}
)) != EOF) {...}
ファイルabc 'a' != EOF は真 ファイルabc
'a'
'b'
'c'
'¥n' プログラムの 内部状態FILE
オブジェ
fp
オブジェ
クト
fp
c = ???
'a'
61文字ごとの読み出し(3)
1文字ごとの読み出し(3)
while ((c =
while ((c = fgetc
fgetc(
(fp
fp)) != EOF) {...}
)) != EOF) {...}
ファイルabc ファイルabc
'a'
'b'
'c'
'¥n' プログラムの 内部状態FILE
オブジェ
fp
オブジェ
クト
fp
c = ???
'¥n' 71文字ごとの読み出し(4)
1文字ごとの読み出し(4)
while ((c =
while ((c = fgetc
fgetc(
(fp
fp)) != EOF) {...}
)) != EOF) {...}
ファイルabc EOF != EOF は偽 ファイルabc
'a'
'b'
'c'
'¥n' プログラムの 内部状態FILE
オブジェ
fp
オブジェ
クト
fp
c = ???
EOF
8EOF(1)
EOF(1)
「ファイルの終わり(End Of File)」を表す定数.
stdio hで
#define EOF (
#define EOF (‐
‐1)
1)
などと定義されている
stdio.hで,
#define EOF (
#define EOF (‐
‐1)
1)
などと定義されている.
unsigned char signed char g ASCII (7ビット) 0 1 128 ‐1 0 127 255 ‐128 127 255 ナル EOF 9 ナル 文字 EOF リp.457 入p.189
EOF(2) フ イルアクセス
EOF(2),ファイルアクセス
文字(バイト)単位で読み書きするとき
文字(バイト)単位で読み書きするとき
intint型を使用する型を使用する intint型を使用する.型を使用する. • signed char型だと,255をEOFと誤認識する. • unsigned char型だと EOFを255と誤認識する • unsigned char型だと,EOFを255と誤認識する. • EOFから255までの「257種類の値」は,char型(signed char型 unsigned char型)で区別できない! char型,unsigned char型)で区別できない! 読み出してEOFが来たら,そこでおしまいにする. ライブラリ関数はfgetc getcharなど ライブラリ関数はfgetc, getcharなど 文字列単位で(何バイトか一括して)読み書きするとき
配列または 型を使用する char配列またはchar*型を使用する. ライブラリ関数はfgets, freadなど 10 リp.461, p.471, p.462, p.466標準入力と標準出力
標準入力と標準出力
標準入力(standard input,
stdin
stdin
)
通常はコンソール入力(キーボード入力)
stdin,stdoutは FILE *型の値
( イ ポイ タ)と
通常はコンソ ル入力(キ ボ ド入力)
標準出力(standard output,
stdout
stdout
)
通常はコンソ ル出力(画面表示) (ファイルポインタ)として 利用可能.ただし代入は できない. 通常はコンソール出力(画面表示) シェルのリダイレクション機能を用いて変更可能.
実 例 実行例: find ~ > files 実行例: ./line2 < /usr/share/dict/words シェルのパイプ機能を用いて,あるプログラムの標準出力と
別のプログラムの標準入力を接続できる.
実行例: echo '1+2*3' | bc 11 リp.480 入pp.183-186 line2.c標準入力 標準出力とコンソ ル
標準入力・標準出力とコンソール
実行環境 実行環境 (OSなど) 標準入力 コンソール 実行プログラム コンソ ル 'a''b''c''¥n' $ /line2 実行プログラム 'a''b''c''¥n' '1' ':'' ' $ ./line2 abc 1: abc $ 標準出力 $ 実行コマンド 入力(エコーバック) 出力 12 入p.188標準入力に関するライブラリ関数
標準入力に関するライブラリ関数
int
getchar
getchar
(void);
標準入力から1文字(1バイト)読み込む
標準入力から1文字(1バイト)読み込む.
戻り値はunsigned char型の値,もしくは定数EOF.
char *
gets
gets
(char *s);
なるべく使わない!
char *
gets
gets
(char *s);
標準入力から1行読み込み,sの指す領域に格納する. 行が の領域サイズよりも大きいとしても そのまま格納しよ なるべく使わない! 1行が,sの領域サイズよりも大きいとしても,そのまま格納しよ うとする.
i t
f
f
(
t h
*f
t
)
なるべく使わない!
int
scanf
scanf
(const char *format, ...);
formatに従って標準入力から入力を読み込み,第2引数以降 が参照する領域に格納する が参照する領域に格納する. 読み込みに失敗すれば,入力が進まない. 13 リpp.471-472, pp.476-477, pp.489-492
標準出力に関するライブラリ関数
標準出力に関するライブラリ関数
int
putchar
putchar
(int c);
cをunsigned char型に変換した上で 標準出力に(1文字)
cをunsigned char型に変換した上で,標準出力に(1文字)
書き出す.
char *
puts
puts
(const char *s);
char
puts
puts
(const char s);
文字列sと改行文字を標準出力に書き出す.
int
printf
printf
(const char *format
);
int
printf
printf
(const char *format, ...);
formatに従って標準出力に書き出す. ( ) ( ) ×× printf(str); printf("¥n"); ○○ puts(puts(strstr);); 文字列に % が ○○ printfprintf(("%s%s¥¥n", n", strstr);); 文字列に % が 含まれていると おかしくなる 14 リp.474, p.473, pp.485-488
標準入出力と標準入出力関数
標準入出力と標準入出力関数
標準入力・標準出力に対する関数は,標準入出力関数およ
びstdin, stdoutを用いた関数形式マクロにより定義され
びstdin, stdoutを用いた関数形式マクロにより定義され
ている(ことがある).
例: #define#define getchargetchar()() getcgetc(stdin)(stdin) 例: #define#define getchargetchar()() getcgetc(stdin)(stdin)
15
実行時の領域確保について
実行時の領域確保について
プログラム実行時(main関数に制御が移る前)に
静的変数のオブジェクトが確保 初期化される 静的変数のオブジェクトが確保,初期化される. • プログラム終了時に破棄される. ブロック({
})が実行されるときに
ブロック({...})が実行されるときに
自動変数のオブジェクトが確保される. ブ ク終了時に破棄される スタック領域 • ブロック終了時に破棄される.
記憶域管理関数(
malloc
malloc
,
calloc
calloc
など)を呼び出すと
オブジェクトとして使用できる領域が確保される. • • freefreeなどの関数が呼び出されるか, ヒープ領域 プログラム終了時に破棄される. mallocの語源:memory allocation(メモリ割り当て) ヒ プ領域 16 入pp.245-246
ll
の使い方(1)
mallocの使い方(1)
準備
#include <#include <stdlib hstdlib h>>
ずポ
#include <#include <stdlib.hstdlib.h>>
intint *p;*p;
p (
p (int
int *)
*)malloc
malloc(
(sizeof
sizeof(
(int
int));
));
必ずポインタ型
(intの部分は用途による)
p = (
p = (int
int *)
*)malloc
malloc(
(sizeof
sizeof(
(int
int));
));
⇒ *pがint型オブジェクトとして利用可能.
p
*p
sizeof(int)バイトの領域
17
ll
の使い方(2)
mallocの使い方(2)
準備
#include <#include <stdlib hstdlib h>>
ずポ
#include <#include <stdlib.hstdlib.h>>
intint *p;*p;
p (
p (int
int *)
*)malloc
malloc(
(sizeof
sizeof(
(int
int) * 10);
) * 10);
必ずポインタ型
(intの部分は用途による)
p = (
p = (int
int *)
*)malloc
malloc(
(sizeof
sizeof(
(int
int) * 10);
) * 10);
⇒ p[0],p[1],…,p[9]がintの配列であるかのように
利用可能
利用可能.
p
p[0] p[1]
…
p[9]
sizeof(int) * 10 バイトの領域 18 リp.235, p.341, p.501ll
使用の注意点
malloc使用の注意点
領域の値は不定であるため,必要に応じて初期化する.代
わりに
calloc
calloc
を使用すれば,すべて0に初期化された領域
わりに
calloc
calloc
を使用すれば,す
て0に初期化された領域
が得られる.
代入される変数はポインタ変数なので 左辺値になり得る
代入される変数はポインタ変数なので,左辺値になり得る
(
p++;
p++;
などとできる).
領域確保に失敗するとNULLを返すので
領域確保に失敗するとNULLを返すので,
if ((p = (pif ((p = (pの型名の型名))mallocmalloc((バイト数バイト数)))) == NULL) {== NULL) { エラー処理 エラー処理 エラ 処理 エラ 処理 } }
とするのが一般的.
する
般的
必ずポインタ型 19 リp.497行列の動的な確保
行列の動的な確保
typedeftypedef structstruct MatrixMatrix {{
int
int row, column;row, column;
d bl **
d bl ** ll tt
double **
double **element;element; }
} matrixmatrix;;
matrix *p = (matrix *)
matrix *p = (matrix *)mallocmalloc((sizeofsizeof(matrix));(matrix)); p
p-->row = 2; p>row = 2; p-->column = 3;>column = 3; p
p-->element = (double **)>element = (double **)mallocmalloc((sizeofsizeof(double *) * 2);(double *) * 2); p
p-->element[0] = (double *)>element[0] = (double *)mallocmalloc((sizeofsizeof(double) * 3);(double) * 3); p
p [ ][ ] (( )) (( (( )) );); p
p-->element[1] = (double *)>element[1] = (double *)mallocmalloc((sizeofsizeof(double) * 3);(double) * 3);
row=2 l 3 0行 1行 a00 a01 a02 a10 a11 a12 p column=3 element a00 element 10 11 12 a01 a02 a10 a11 a12 20 matrixfile.c
i行j列の成分(aij)は pp‐‐>element[i][j]>element[i][j]