[時間割:C言語]『はじめてのC言語完全入門』その9
2008/11/04 00:34 posted by kunkichi
ここ2、3日の間、ポインタと格闘していました。ポインタ単体の意味は理解できるのだけど、配列とごっちゃになった瞬間もうわかりません、、、他の言語と比べると、C言語ではどうも配列とポインタの区別が曖昧な印象があるんだよね。
これはちょっとまずいってんで、その部分だけもう少ししっかり勉強しようと言うことで、教科書増やしました。
谷尻 かおり 谷尻 豊寿
技術評論社
売り上げランキング: 209427
前橋 和弥
技術評論社
売り上げランキング: 9027
両方ともヤフオクでゲットしたので比較的懐を痛めずに済みました(笑)
ここまでの印象では他言語と特に大きく変わるところもなかったし、特につまずいたところもなかったのですが、ここはC言語の一番の山場っぽいので苦戦しそうです。もう少し格闘してみたいと思います。
Category: C, Programming | コメント&トラックバック(1)
[時間割:Perl]『ミニマルPerl』その7
2008/10/31 02:40 posted by kunkichi
今日も外で勉強してきました。やっぱり外はいいですね。ということで木曜日は『Perl』です。今回からsedをPerlで置き換えてみようというところです。
Tim Maher
オライリージャパン
売り上げランキング: 96883
- おなじみの置換。sedとほとんど同じ。
$ echo "abcde" | perl -wpl -e 's/abc/ABC/g;'
ABCde
- 複数の置換を一気に。まずはsed。これは知らなかった。
$ cat example.sed
s/a/A/g
s/b/B/g
s/c/C/g$ echo "abcde" | sed -f example.sed
ABCdeこれをPerlで。コマンドラインだとこんな感じ。$ echo "abcde" | perl -wpl -e '
> s/a/A/g;
> s/b/B/g;
> s/c/C/g;'
ABCdeスクリプトだと以下。$ cat example.pl
#!/usr/bin/perl -wpl
s/a/A/g;
s/b/B/g;
s/c/C/g;$ echo "abcde" | ./example.pl
ABCde
- 行を指定して置換。sedの場合。
$ cat sample.txt
This is sentence 1.
This is sentence 2.
This is sentence 3.$ sed '1s/sentence/REVISED_SENTENCE/g;' sample.txt
This is REVISED_SENTENCE 1.
This is sentence 2.
This is sentence 3.Perlだと行番号を表す$.を使う。$ perl -wpl -e '$. == 1 and s/sentence/REVISED_SENTENCE/g;' sample.txt
This is REVISED_SENTENCE 1.
This is sentence 2.
This is sentence 3.
- -0digitを使って、段落単位、ファイル単位もできる。
$ cat sample2.txt
This is paragraph 1.
And, this is a sentence for paragraph 1.
This is paragraph 2.
And, this is a sentence for paragraph 2.
This is paragraph 3.
And, this is a sentence for paragraph 3.$ perl -00 -wpl -e '$. == 1 and s/paragraph/PARAGRAPH/g;' sample2.txt
This is PARAGRAPH 1.
And, this is a sentence for PARAGRAPH 1.
This is paragraph 2.
And, this is a sentence for paragraph 2.
This is paragraph 3.
And, this is a sentence for paragraph 3.
- 後方参照。sedとPerlだとマッチ部分のカッコのエスケープが逆なので注意。まずsed。
$ echo "This is a sample sentence." | sed 's/^\(.*\) \(sentence\.\)$/\1 REVISED \2/g'
This is a sample REVISED sentence.sedはカッコにエスケープをつけると正規表現の部分マッチ用のカッコとなる。次にPerl。$ echo "This is a sample sentence." | perl -wpl -e 's/^(.*) (sentence\.)$/$1 REVISED $2/g'
This is a sample REVISED sentence.Perlの場合は逆にエスケープをつけない場合が正規表現のマッチ用カッコとなる。
- 行番号で表示を指定。例として2行目以降を出力してみる。
$ sed -n '2,$p' sample.txt
This is sentence 2.
This is sentence 3.Perlだとこんな感じ。$ perl -wnl -e '$. > 1 and print;' sample.txt
This is sentence 2.
This is sentence 3.
- もちろん、さっきとおんなじように、-0digitを使えば、段落単位・ファイル単位とかも可能
sedで後方参照する時っていつもカッコのエスケープ忘れてハマるんだよね、苦笑。行番号の箇所なんかもキー入力はPerlのほうが少し多くなるけど、直感的。
Category: Programming, Perl | コメント&トラックバック(0)
[時間割:Perl]『ミニマルPerl』その6
2008/10/28 01:49 posted by kunkichi
火曜日は『Perl』の時間です。行をまたがる正規表現のところから。
- 普通は . でニューライン(¥n)はとれないのだけど、シングルラインモードを使えば¥nもマッチ対象とすることができる。これを使って複数行にまたがるマッチングを行う。
$ cat lines.txt
abcde fghij
klmno pqrst
uvwxyz$ perl -00 -wnl -e '/\bfghij\b.*\bklmno\b/si and print $&;' lines.txt
fghij
klmno
- ポイントは以下。
- 入力レコードセパレータを-00とか-0777とか複数行読み込めるものにする。
- マッチ修飾子にシングルラインモード(s)を有効にして、¥nがマッチするような正規表現を書く。*. とか。
- いろいろ試してみる。BINDのqueryログから、問い合わせホスト名が2文字のTLDで終わっているものを参照。
$ perl -wnl -e '/query: \S+\.[a-z][a-z] /i and print;' query.log27-Oct-2008 23:28:02.221 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: atode.cc IN A +
27-Oct-2008 23:54:14.192 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: www.uniqlo.jp IN A +
27-Oct-2008 23:59:02.339 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: www.oreilly.co.jp IN A +さらに.jpドメインのものを除外する。$ perl -wnl -e '/query: \S+\.[a-z][a-z] /i and ! /query: \S+\.jp /i and print;' query.log27-Oct-2008 23:28:02.221 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: atode.cc IN A +
- String::Approxを使ってファジーマッチングも可能。
# cat fuzzy_match
----------
#!/usr/bin/perl -s -wnl
use String::Approx 'amatch';
amatch $pattern, [ "i", "20%" ] and print;
----------echo "yafoo" | ./fuzzymatch -pattern='yahoo'
yafoo
- スクレイピングの例。www.php.netの右上にあるStableのバージョンのうち、5.X系のバージョンを取得する。
$ lwp-request -o text www.php.net | perl -wnl -e '/Stable/ and /5\.\d\.\d/ and print $&;'
5.2.6
以下、grep処理のまとめ
| grepコマンド |
Perlでの書き方 |
| grep ‘〜’ |
perl -wnl -e ‘/〜/ and print;’ |
| grep -v ‘〜’ |
perl -wnl -e ‘/〜/ or print;’ |
| grep -i ‘〜’ |
perl -wnl -e ‘/〜/i and print;’ |
| grep -l ‘〜’ |
perl -wnl -e ‘/〜/ and print $ARGV and close ARGV;’ |
| fgrep ‘〜’ |
perl -wnl -e ‘/¥Q〜¥E/ and print;’ |
シチュエーションによってはgrepのほうが簡単な場合もあるけど、まあそこはケースバイケースで。ちょくちょく使って慣れていこう。。
Category: Programming, Perl, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その8
2008/10/25 22:49 posted by kunkichi
今週の頭は少しサボっちゃいましたが、気を取り直して。サボりの元凶となったのは Touch Diamond を買ったから(笑)ですが、遊びのために買ったんじゃない、ということを証明するために早速、金曜日の会社帰りに外で勉強しました。やっぱり外ははかどるな〜、3章一気に進んじゃったし。
ということで、木・金のアップです。まずは『C言語』の方から。
塚越 一雄
技術評論社
売り上げランキング: 420963
関数
スコープ
- 関数内の変数は関数内にのみ限定される(ローカル変数)。
- 実際には「ブロック」内、つまり{}で囲まれた範囲内に限定されているのがローカル変数。
- 関数の外側の変数は、関数から見た場合にはグローバル変数となり、参照可能。
- 変数名もブロック内に限定されるので、他の関数内で同じ変数名が使用されていても衝突しない。
- ただし、グローバルな変数名と同じ名前にした場合、関数内ではローカル変数が優先される。
- グローバル変数はファイルスコープ。
配列
- 配列にも型の概念がある。すなわち、同じ型のデータしか入れれない。異なる型のデータを入れるのは構造体。
- 配列は、基本の型とは異なるユーザ定義型の一つ。
- 配列を宣言するには、型・配列名・サイズ(要素数)をあらかじめ定義する。
int ary[10]
- 初期値を与えることもできる。
int ary[] = { 1, 2, 3 };この場合はサイズの指定は不要(自動的に初期値の個数がサイズとなる)
- 配列の要素へのアクセスは、インデックスを使う。
x = ary[0];
- 配列全体のメモリ量を求めるには 配列に対して sizeof を使う。
sum = sizeof ary;
- 配列要素の単体メモリ量を求めるには 配列のインデックス0 に対して sizeof を使う。
each = sizeof ary[0]
- つまり、全体メモリ量を単体メモリで割ると、配列の要素数を求めることができる。
num = sizeof ary / sizeof ary[0];forループの上限値等に設定する場合はこれをつかうとよろし。
- forループの脱出にもbreakが使える。
- ループの脱出にはbreakを使う。
- 配列はあらかじめサイズを指定しておかないといけないため、途中でサイズが大きくなった場合に対応できない。こういう場合は動的メモリが必要となる。
ふぅ、たくさん進んだ分、アウトプットも多くなってしまいましたが、これで教科書の残り3分の1まで来ました。やっと終わりが見えてきたのでがんばります。次はいよいよ「ポインタ」です!
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:Perl]『ミニマルPerl』その5
2008/10/15 02:05 posted by kunkichi
さて、祝日分のアップをします。まずは『Perl』から。
Tim Maher
オライリージャパン
売り上げランキング: 96883
- 正規表現でこれまでは、デリミタに¥s+、数値に[0-9]とかでベタに指定してたけど、これからは¥bとか¥dとか使おう。
- fgrepみたいな、メタキャラクタをそのままリテラルで使う場合は、¥Q…¥E。
- マッチした部分を取り出す場合は、$&を使う。
$ echo "12345 123 abced abc" | perl -wnl -e '/\b\d\d\d\d\d\b/ and print $&;'
12345
- マッチしない場合(grep -v)は、orを使う。
$ echo "12345
> 123
> abcde
> abc" | perl -wnl -e '/\b\d\d\d\d\d\b/ or print;'
123
abcde
abc
- 合致するファイル名だけを出力する(grep -l)の場合は、$ARGVでファイル名を取得。
perl -wnl -e '/\b\d\d\d\d\d\b/ and print $ARGV and close ARGV;' aaa bbb ccc
aaa最後にcloseしているのは、合致する文字列が複数業あった場合にファイル名が2重に出力されるのを防ぐために、合致した時点でcloseして終わるため。
ちなみに、closeしないとこうなる。$ perl -wnl -e '/\b\d\d\d\d\d\b/ and print $ARGV;' aaa bbb ccc
aaa
aaa
- 大文字小文字を無視する(grep -i)の場合は、マッチ修飾子iを使う。
$ echo "aaa
> AAA
> bbb
> BBB" | perl -wnl -e '/aaa/i and print;'
aaa
AAA
- egrep的だったり、パイプを使った段階的フィルタ、みたいなのはperlだと簡単。
perl -wnl -e '/aaa/ and
/bbb/ and
/ccc/ and
/ddd/ and
print;' sample.txtパイプで書くとgrep "aaa" sample.txt | grep "bbb" | grep "ccc" | grep "ddd"メモリ消費やポータビリティの点でPerlのほうがらくちん。
- 行単位じゃなくて、複数行でのマッチングも簡単。まずは段落。以下のようなldifファイルがあるとして、
$ cat sample.ldif
dn: uid=test1,ou=people,dc=example,dc=com
uid: test1
objectclass: posixAccount
objectclass: account
userPassword:password1
loginshell: /bin/bash
uidNumber: 201
gidNumber: 201
homeDirectory: /home/test2
gecos: test1
description: "Test User 1"
・・・
dn: uid=test3,ou=people,dc=example,dc=com
uid: test3
objectclass: posixAccount
objectclass: account
userPassword:password3
loginshell: /bin/bash
uidNumber: 203
gidNumber: 203
homeDirectory: /home/test3
gecos: test3
description: "Test User 3"uidがtest2のレコードを抽出。$ perl -00 -wnl -e '/uid: test2/ and print;' sample.ldif
dn: uid=test2,ou=people,dc=example,dc=com
uid: test2
objectclass: posixAccount
objectclass: account
userPassword:password2
loginshell: /bin/bash
uidNumber: 202
gidNumber: 202
homeDirectory: /home/test2
gecos: test2
description: "Test User 2"
- 今度はさっきのレコードがそれぞれ独立したldifファイルだった場合。この場合はファイルモードを使う。
$ perl -0777 -wnl -e '/uid: test2/ and print;' test1.ldif test2.ldif test3.ldif結果は上と同じ。
ここまでは今までにも出てきてるので問題ないね。段落モードとか実際に使えそうなシチュエーションを想定してやってみました。
さて、次回は、「行をまたがる正規表現」からです。これは結構必要となるシチュエーションが多いので重要ですね。
Category: Programming, Perl, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その7
2008/10/15 00:36 posted by kunkichi
連休明けですががんばります。ということで先週〜連休中にかけての分はそのうちアップします。今日は『C言語』。
塚越 一雄
技術評論社
売り上げランキング: 420963
高度な選択文
- else if、switch、ifのネスト、三項演算子、この辺はほぼ他言語と同じ。
- 論理演算子のTIPS(というかひねりが効いたやり方)
#include <stdio.h>
int main()
{
int num1, num2;
num1=0;
num2=0;
printf("整数? ");
scanf("%d",&num1);
if( num1 && (num2=100) )
printf("num1=%d, num2=%d \n",num1,num2);
else
printf("num1=%d, num2=%d \n",num1,num2);
return 0;
}./sample
整数? 0
num1=0, num2=0
$ ./sample
整数? 1
num1=1, num2=100すなわち、&&を使った論理演算子の場合、最初の評価が偽だった場合は二つ目の評価は行わない。これを利用して、最初の評価が真だった場合のみ、代入を行う。
- ||の場合は逆になり、最初が真だった場合は二つ目の評価を行わずに、最初が偽だった場合のみ、二つ目の評価で代入を行う。
#include <stdio.h>
int main()
{
int num1, num2;
num1=0;
num2=0;
printf("整数? ");
scanf("%d",&num1);
if( num1 || (num2=100) )
printf("num1=%d, num2=%d \n",num1,num2);
else
printf("num1=%d, num2=%d \n",num1,num2);
return 0;
}$ ./sample
整数? 0
num1=0, num2=100
$ ./sample
整数? 1
num1=1, num2=0
反復文
- 代入演算子、インクリメント、デクリメントは全く同じ。
- while、do〜while、も同じ。do〜whileってあんまり使ったことないのだけど、入力検査に使うのは納得。
- forも同じやけど、Cの場合、ループ変数の宣言は別途せなあかんと、、、
この辺、目新しいところは特になかったな。まあ初歩レベルってことで。
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その6
2008/10/07 20:54 posted by kunkichi
火曜日は『C言語』です。ちょいご無沙汰でした(^^; がんばります。
入力プログラムの応用
- 定数はdefineを使う。
#define TEISU 400
- 行の最後までが有効になる。
- スペースを含んでもOK。
- 行をまたぐ場合は最後に¥を使う。
- サンプル:
#include <stdio.h>
#define STR "word and space"
#define PARAGRAPH "This is test for paragraph.\
new line"
int main()
{
printf("%s\n" , STR);
printf("%s\n" , PARAGRAPH);
return 0;
}実行結果:$ ./en
word and space
This is test for paragraph. new line
- 定数を置き換えるのはプリプロセッサの地点。gcc -E でプリプロセスだけ行うとよくわかる。
$ gcc -E sample.c
・・・
int main()
{
printf("%s\n" , "word and space");
printf("%s\n" , "This is test for paragraph. new line");
return 0;
}
ifを使った選択文
- 他言語とほとんど一緒。
- 代入「式」を条件に使う
if( a = 4 )はa=4;
if(a)と同じ。
やっと本の半分弱まで来ました。日々の努力が大事です。
Category: C, Programming, Book | コメント&トラックバック(0)
[時間割:Perl]『ミニマルPerl』その4
2008/10/06 22:40 posted by kunkichi
風邪も落ち着いたので今週からまたがんばります!月曜日は『Perl』です。次はPerlでいろいろな*grepコマンドの機能を実装しようという話です。
Tim Maher
オライリージャパン
売り上げランキング: 96883
- *grepの代わりにPerlを使うと方言を統一できる。
- *grepだと特定のメタキャラクタが使えたり使えなかったり(単語境界の¥bとか)
- *grepごとの正規表現の方言の違いがあったり
- 制御文字用のエスケープが豊富。
- *grepだとあったりなかったり
- タブを表すのに、Ctrl+V+タブとかで実際に打つよりも長い、とか。
- ¥dとか¥tとかコンパクトに表せる
- その他の正規表現の方言も考えなくてよい
- 繰り返し、より便利な後方参照、メタキャラクタ自体のクォート、コメントの挿入、もっと高度なものまで。
- マッチング機能
- レコードの単位を段落にしたりファイルにしたり
- 行をまたいでマッチング
- バイナリも扱える
- ディレクトリは自動的に無視
- 拡張機能
- マッチした部分を正規表現の外側で参照
- 出力レコードのセパレータを変更して出力をカスタマイズ
- マッチ演算子
- 通常は/〜/で$_に対するマッチング
- mで始めるとデリミタを変更できる。%をデリミタにすると、
m%〜%
- =~で変数に対するマッチング。もちろんここでもデリミタは変更できる
$str =~ /example/$str =~ m|example|
- 1行だとこんな感じ
$ perl -wnl -e '/example/ and print;' /tmp/sample.txt$ cat /tmp/sample.txt | perl -wnl -e '/example/ and print;'
- -nと-pはディレクトリを無視してくれる。例えば/etc/yum*を参照する場合、
$ ls -td /etc/yum*
drwxr-xr-x 3 root root 4096 7月 20 20:43 /etc/yum
drwxr-xr-x 2 root root 4096 7月 16 00:46 /etc/yum.repos.d
-rw-r--r-- 1 root root 346 6月 22 09:35 /etc/yum.conf
$ perl -wnl -e '/yum/ and print;' /etc/yum*
cachedir=/var/cache/yum
logfile=/var/log/yum.log
# Note: yum-RHN-plugin doesn't honor this.
# in /etc/yum.repos.dディレクトリは無視してyum.confファイルの中身だけを参照してくれる。
- シェルだとシングルクォートのネストはできないので、文字列エスケープ(¥047)を使えばOK。Perlでは普通にバックスラッシュでエスケープできるけど、コマンドラインから実行する場合はあくまでもシェルの制約内。
最近は意識して、仕事でもgrepが使えるケースでもPerlで書いてみるようにしてるので大分なれてきたな〜、この調子この調子。
Category: Programming, Perl, Book | コメント&トラックバック(0)
[時間割:Python]『みんなのPython』その6
2008/09/26 02:31 posted by kunkichi
はい、木曜は『Python』です。
先週はちょっとさぼってしまいましたが、実は前にも『はじめてのPython』の時にもあった「リファレンス」がやっぱりちょっとわかりにくかったので、まとめきれませんでした。
ということで、今週もう一度読み直してみたので、まとめてみます。
柴田 淳
ソフトバンククリエイティブ
売り上げランキング: 50252
- Pythonは参照渡しが基本。なので変数はオブジェクト(実体)と結びついている。
- ただし数値、文字列などの「書き換え不能」なオブジェクトの場合は値渡し。 つまり、リスト、辞書などの「書き換え可能」なオブジェクトはリファレンスとなるので、オブジェクトを呼び出すようなメソッドを使うと、元の変数も変わってしまうので注意。
>>> a=[1,2,3,4]
>>> b=a
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4, 5]
- これを回避するためには、リストをリテラルで代入するか、リストのコピーを代入する。
>>> a=[1,2,3,4]
>>> b=[1,2,3,4]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]リストのコピーを作るにはスライスを使う。>>> a=[1,2,3,4]
>>> b=a[:]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]辞書の場合はスライスは使えないのでcopyモジュールを使う。>>> a={1:"one",2:"two",3:"three"}
>>> import copy
>>> b=copy.copy(a)
>>> a
{1: 'one', 2: 'two', 3: 'three'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
>>> a[4]="four"
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
- copy関数は「浅い」コピー。多次元配列とか書き換え可能なオブジェクトを含む辞書などは「深い」コピー、deepcopy関数を使う。
- 書き換え可能なオブジェクトを関数の引数として渡して関数内でそれを変更すると、関数の外でもオブジェクトが書き換えられるので注意。
>>> def add_str(list):
... list.append('added!')
...
>>> a=[1,2,3,4]
>>> add_str(a)
>>> a
[1, 2, 3, 4, 'added!']
- 関数の引数デフォルト値に書き換え可能なオブジェクトを指定して関数内でそれを変更しても、デフォルト値の代入は1回しか行われないので注意。関数内の変更だけが繰り返される。
>>> def add_str(list=[1,2,3]):
... list.append('added!')
... print list
...
>>> add_str()
[1, 2, 3, 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!', 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str([1,2,3])
[1, 2, 3, 'added!']
>>> add_str()
[1, 2, 3, 'added!', 'added!', 'added!', 'added!']
うーん、Perlでも参照渡しとか普通に使うし、Cで言うポインタも最近仕組みがわかってきたので意味は理解できるんやけど、やっぱりちょっと考えないとサッとイメージできないなぁ。ポインタが鬼門と言われるわけだ。
ちょこちょこスクリプト書いて体で覚えないとね。
Category: Python, Programming, Book | コメント&トラックバック(0)
[時間割:C言語]『はじめてのC言語完全入門』その5
2008/09/17 23:01 posted by kunkichi
火曜日の『C言語』を忘れてたので今日はがんばります!
12章「書式付き入力(その1)」から。
塚越 一雄
技術評論社
売り上げランキング: 420963
- scanfで定型フォーマットのデータを標準入力
scanf("変換仕様",&変数名)
- 複数のデータの場合は以下のような感じで空白で区切るとわかりやすい。
scanf("%c %d %f",&変数名1,&変数名2,&変数名3)とりあえず、区切りの空白は無視されるものとする。
- 標準入力に含まれる空白の扱いに注意
- 空白をフィールドの区切りとする
- 先頭部分の空白は削除される
- ただし、文字の場合のみ空白も改行も含まれる形で入力をとる。
- 変換仕様中の空白は無視されるとしたけど、実際は空白を含めると、入力データの空白を除去したのと同じになる。よって
- 空白を入力したい場合は文字書式(%c)等の前に空白を入れない。
- 空白を除去したい場合は文字書式(%c)等の前に空白を入れる。
- scanfは決まったフォーマットでデータを受けとる前提になっているので、入力エラーに対応できない。ではどうするか?
- scanfはintを返す。返す値は入力に成功したフィールドの数。これを使えば、エラーチェックができる。
int ret;
ret = scanf( "%d", &arg1 );retが1ならOK。0ならNG。でも数値は文字列ともとれるから、単に数値かどうかのチェックしかできない気がする。やっぱり正規表現がいいなぁ、それはまたあとで出てくるのかな?
- ただし複数フィールドの場合に最初のフィールドでエラーになったらscanfはそこで終わってしまうので、その場合はscanfを複数に分ける。
scanf("%d",&argv1);
scanf("%c",&argv2);1行目でエラーになっても2行目のscanfは実行される。
- EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
- 入力フィールドをスキップするには、変換仕様のフォーマットに*を含める。
scanf("%d %*d %d", &arg1, &arg3 )この例だと元データの2番目のフィールドはスキップされる。
- EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
- scanfの書式文字列に、変換仕様や空白以外を含めると、その文字列を含めた一連のフォーマット文字列の入力とすることができる。日付とかで便利かも。
scanf("%s/%s/%s", &y, &m, &d);
- scanfの書式文字列に”¥n”を含めると入力が終わらなくなるので注意!
ふぅ〜、とりあえずこれで入出力を両方できるようになりました。でもこれじゃちょっと入力チェックが弱すぎだな〜。もう少し進めば正規表現とかも出てくるのかな?がんばります。
『サーバ』は引き続き↓読んでます。アウトプットがなかなか難しいですが、そのうち。
デイビッド・A. パターソン ジョン・L. ヘネシー
日経BP社
売り上げランキング: 37621
Category: C, Programming, Book | コメント&トラックバック(0)
2012/02/07/ 18:03
2012/01/04/ 07:43
2011/10/06/ 10:13
2011/10/06/ 07:03
2011/10/06/ 06:46