12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと

Slides:



Advertisements
Similar presentations
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
Advertisements

復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
データ構造とアルゴリズム 第10回 mallocとfree
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
第8回 プログラミングⅡ 第8回
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
ファイル操作と文字列の利用.
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング論 関数ポインタ と 応用(qsort)
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング論 ファイル入出力
プログラミング応用 printfと変数.
プログラミング論 II 2008年10月30日 文字列
プログラミング 4 記憶の割り付け.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
第10章 これはかなり大変な事項!! ~ポインタ~
04: 式・条件分岐 (if) C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
第7回 プログラミングⅡ 第7回
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
09: ポインタ・文字列 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
情報処理Ⅱ 第2回:2003年10月14日(火).
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
プログラミング基礎a 第6回 C言語によるプログラミング入門 配列と文字列(その2)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング 3 2 次元配列.
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
09: ポインタ・文字列 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
ネットワーク・プログラミング Cプログラミングの基礎.
第5回 プログラミングⅡ 第5回
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング 4 文字列.
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
第1章 文字の表示と計算 printfと演算子をやります 第1章 文字の表示と計算.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと http://www-it.sci.waseda.ac.jp/ teachers/w483692/CPR1/ 2015-06-29

まとめ:ポインタを使った処理 内容 説明 呼び出し元の変数を書き換える 第 9 回 文字列を渡す・配列を渡す 第 10 回 ファイルポインタ 複数の値を返す 第 11 回 大きな領域を確保する 2015-06-29 C プログラミング入門 総機1 (月1)

今回の内容 コマンドライン引数の取り扱い 文字列から数値への変換 シェルから引数 (オプション) を受け取る 技術的には二重ポインタ (double pointer) である ポインタへのポインタ 秋期の「Cプログラミング」で使うが、この講義ではあまり踏み込まない 文字列から数値への変換 コマンドライン引数は単なる文字列なので、数値として扱うには変換が必要 2015-06-29 C プログラミング入門 総機1 (月1)

復習:アドレスとポインタ メモリ上の位置を表す値 型を持つ 変数 a のアドレスは &a ポインタ変数に格納できる アドレス値のことをポインタとも呼ぶことがある int a { int a = 100; int *p = &a; printf("%d", *p); 100 int *p 矢印が指す位置のアドレスを持っている 2015-06-29 C プログラミング入門 総機1 (月1)

デリファレンス演算子 * で、アドレスが指す位置の内容を読み書きできる 添え字演算子 [] で、ポインタの指す位置をずらして読み書きできる 復習:アドレス演算と読み書き デリファレンス演算子 * で、アドレスが指す位置の内容を読み書きできる 添え字演算子 [] で、ポインタの指す位置をずらして読み書きできる ポインタ p に対して *(p+n) と p[n] は同じ -23 85 p[0] == *p == 23 p[1] == *(p+1) == 85 p メモリ上のデータをどんな値とみなすかは、ポインタの型で決まる 矢印が指す位置のアドレスを持っている 2015-06-29 C プログラミング入門 総機1 (月1)

配列変数名は、式中で配列の先頭へのポインタとなる 復習:配列とポインタ 配列変数名は、式中で配列の先頭へのポインタとなる 配列変数を a とすると a そのものがアドレス &a[0] (0 番要素のアドレス) と同じ &a と書いてもよい それぞれ型が異なる場合があるが詳細は省略する。ポインタに関する専門書を参照 int a[4] 365 a[0] == *a == p[0] == *p == 365 p p = &a という代入をした場合 2015-06-29 C プログラミング入門 総機1 (月1)

文字列は、メモリ上の文字 (char 型の値) が並んでいる領域の先頭へのポインタである 復習:文字列 文字列は、メモリ上の文字 (char 型の値) が並んでいる領域の先頭へのポインタである なぜ char 型なのかは歴史的な事情による 日本語を含む場合でも、基本的には char でよい 文字列リテラルを書くと、その文字列がシステム領域に用意され、その先頭ポインタを表す 文字列の終端は null 文字 ('\0') である 配列を文字列リテラルで初期化すると、自動的に付加される 2015-06-29 C プログラミング入門 総機1 (月1)

コマンドライン引数 シェルでコマンド名の後ろに書く文字列 ホワイトスペースで分割される (トークン化) コマンドは受け取った引数を処理する [user@host]$ gcc src.c -o src -Wall -Wextra この場合、 5 個の引数を gcc というプログラムに渡している [user@host]$ ./src hello world C 言語で書いたプログラムに引数を渡した場合、どのように処理すればいいのか? 2015-06-29 C プログラミング入門 総機1 (月1)

main 関数として以下のプロトタイプを使う コマンドライン引数の受け取り方 main 関数として以下のプロトタイプを使う int main(int argc, char** argv); cf. 今までのは int main(void); 引数名は何でもよいが慣用的に argc, argv または ac, av が使われる それぞれ、 argument count と argument vector (引数の列) という意味 第2引数の書き方として、 char **av char *av[] のどちらでも、文法上は同じである。後者の書き方をする人もいるので覚えておく 2015-06-29 C プログラミング入門 総機1 (月1)

argv の内容 文字列へのポインタの配列 最後に null ポインタで終わる ./prog hello world 100 と実行した場合 char **argv argv[4] == NULL main 関数の自動変数の領域 システムのメモリ領域 argv[0][0] argv[0] '.' '/' 'p' 'g' 'r' 'o' '\0' argv[1] 'h' 'e' 'l' '\0' 'o' たとえば argv[1] が "hello" という文字列だと思えばよい 'w' 'o' 'r' '\0' 'l' 'd' '1' '0' '\0' 2015-06-29 C プログラミング入門 総機1 (月1)

null ポインタの入っている要素の番号を表す argc の意味 null ポインタの入っている要素の番号を表す n 個の引数を指定すると argc == n+1 ./prog hello world 100 と実行した場合 この例の場合 argc == 4 つまり、指定した引数の個数 + 1 char **argv argv[argc] == NULL main 関数の自動変数の領域 システムのメモリ領域 argv[0][0] argv[0] '.' '/' 'p' 'g' 'r' 'o' '\0' argv[1] 'h' 'e' 'l' '\0' 'o' 'w' 'o' 'r' '\0' 'l' 'd' '1' '0' '\0' 2015-06-29 C プログラミング入門 総機1 (月1)

例題:引数をすべて表示する argv[i] を i = 1, ..., argc-1 まで表示 プログラム名が arg の場合 int main(int argc, char **argv) { int i; printf("%d arguments:\n", argc-1); for(i = 0; i < argc; ++i) printf("[%d] == \"%s\"\n", i, argv[i]); } return 0; [user@host]$ ./arg hello 123 2 arguments [0] == "./arg" [1] == "hello" [2] == "123" argc までループさせない なぜなら、 argv[argc] == NULL なので表示できない 2015-06-29 C プログラミング入門 総機1 (月1)

例題:引数をすべて表示する (別の書き方) argv はポインタ変数であり、直接移動させることもできる プログラム名が arg の場合 int main(int argc, char **argv) { printf("%d arguments:\n", argc-1); for( ; *argv != NULL; ++argv) printf("\"%s\"\n", *argv); } return 0; [user@host]$ ./arg hello 123 2 arguments "./arg" "hello" "123" *argv は argv[0] と同じであり、 argv 自体を動かしていくと、 *argv が表す文字列が変わっていく NULL が現れるまで動かすので、 argc は必要ない 初期化条件は空 ポインタを動かすだけでは何番目かがわからない。必要なら変数を用意してカウントする 2015-06-29 C プログラミング入門 総機1 (月1)

とりあえず、 argv[i] が、 i 番目の引数、と考えるだけで OK 難しいと思う人は… とりあえず、 argv[i] が、 i 番目の引数、と考えるだけで OK ただし、 i は 1 からカウント 最低限 p. 12 のプログラムが使えればよい 2015-06-29 C プログラミング入門 総機1 (月1)

引数はシステム領域に作られるので、 (const はついていないが) 書き換えてはいけない コマンドライン引数の注意 引数はあくまでも文字列である たとえば、 100 と書いても、 "100" という文字列でしかない 数値として扱うには標準ライブラリ関数で変換する (次のスライドで説明) 引数が空文字列になる場合もある たとえば、 ./prog "" abc と書いて実行すると、 argv[1] は空文字列、 argv[2] は "abc" 引数はシステム領域に作られるので、 (const はついていないが) 書き換えてはいけない 2015-06-29 C プログラミング入門 総機1 (月1)

sscanf() は、文字列を解析して変数に値を書きこむ プログラム名が arg の場合 int main(int argc, char **argv) { int i; printf("%d arguments:\n", argc-1); for(i = 1; i < argc; ++i) int v = -1; sscanf(argv[i], "%d", &v); printf("[%d] == \"%s\" (%d)\n", i, argv[i], v); } return 0; [user@host]$ ./arg hello 123 abc 3.14 4 arguments [1] == "hello" (-1) [2] == "123" (123) [3] == "abc" (-1) [4] == "3.14" (3) 整数として変換する 整数として変換できない文字列だった場合は何もしない 整数として変換できるところまで使われる 変換対象の文字列 2015-06-29 C プログラミング入門 総機1 (月1)

sscanf() は、文字列を解析して変数に値を書きこむ プログラム名が arg の場合 int main(int argc, char **argv) { int i; printf("%d arguments:\n", argc-1); for(i = 1; i < argc; ++i) double v = -1; sscanf(argv[i], "%lf", &v); printf("[%d] == \"%s\" (%f)\n", i, argv[i], v); } return 0; [user@host]$ ./arg hello 123 abc 3.14 4 arguments [1] == "hello" (-1.000000) [2] == "123" (123.000000) [3] == "abc" (-1.000000) [4] == "3.14" (3.140000) double として変換する 小数の値として解釈されている l (エル) は不要 2015-06-29 C プログラミング入門 総機1 (月1)

文字列を数値に変換する関数として<stdlib.h> に以下の 2 種類がある 文字列を数値に変換する (2) 変換関数 文字列を数値に変換する関数として<stdlib.h> に以下の 2 種類がある atox() は簡単に使えるが、変換に失敗したかどうかを判断できない float ではない 関数名 変換する型 備考 atoi int 範囲外の値だった場合の戻り値は未定義。 変換に失敗した場合は 0 を返す。 (関数名は ASCII to x という意味 ASCII は文字コードのこと) atol long int atof double strtol 変換に変換に失敗した場合は 0 を返す。 失敗した位置をポインタとして得られる。 strtol, strtoul は基数 (何進法表記か) を指定する。 (関数名は string to x という意味) strtoul unsigned long int strtod 2015-06-29 C プログラミング入門 総機1 (月1)

文字列を数値に変換する (2) 変換関数 なるべく右の strtox() を使うべき { int x; char *s = "2014.2"; x = atoi(s); printf("\"%s\" == %d\n", s, x); { int x; char *s = "2014.2"; char *p; x = strtol(s, &p, 10); printf("\"%s\" == %d", s, x); // 変換が完全に失敗した場合 if(str == p) { ... 変換の失敗位置が必要なければ、 NULL を渡してもよい 10進数を指定 p は変換に失敗した最初の位置である もし、文字列の先頭と同じなら、1文字も解釈できなかったことになる #include <stdlib.h> int atoi(const char *str); long strtol(const char *str, char **str_end, int base ); atoi, strtol のプロトタイプ 2015-06-29 C プログラミング入門 総機1 (月1)