306578 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

giru0116のブログ

giru0116のブログ

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
2007.02.08
XML
カテゴリ:C言語
さて、前回の続きで今回も配列で行きます。
ただ、今回の内容のほうが厄介ですし、今回の内容で作ったプログラムを人に渡すとかは
止めてください。 バグ起こす可能性が非常に高いですから(汗
何故バグが起きやすいのかはその時に解説します。

char型の配列



さて、今まででint型、double型といった整数、実数型の配列を使ってきました。
ここでは文字型であるchar型の配列を紹介します。
これもまた配列の力と言ってもいいんじゃないかと思います。
これまでのchar型といえば正直何か使う機会が乏しかったと思われます。
何せ1文字単位でしたからね… 何に使えというのかって感じですよね(汗
まぁ使いようによっては1文字単位でも十分に使えるわけですが…

しかし、配列になるとchar型は急激に使用度が上がります。
これはchar型の配列では1文字ではなく、文字列が扱えるからです

文字列を扱ったプログラムの例を示します。

array07

さて、この上のプログラムについては初めて出てきたものが多いです。
1つめとしては""で囲んでいますが、これは初期化時のみ有効です。
初期化ってのは宣言と同時に値を入力する事 でしたね。
初期化のとき以外はmojiretu[0] = '*';のようにしなければいけません。(*は任意の文字)

これはint, double型の配列での a[2] = {5, 3};も同じです。

十八章の時には説明し忘れていました。すみませんm(_ _)m

2つめが「%s」です。 これは%cが1文字を表示するもの。
%dが整数を表示するもの。%fが実数を表示するものです。
そして入力の場合は%c,%d,%lfだったりしました。 %sは文字列を入力、出力する際に使用します。
これはさほど難しくないので問題ないと思います。 覚えるだけですし。
ただ、次のが問題なんですよねぇ…。 scanf関数の入力された文字列を格納する部分。
これまで整数だったら「a」とかこんな感じのものに格納してましたね。
今回はあの「&」がありません。 以前第七章の時に「&」の意味を理解しなくても問題ないと書きました。
また今回も別に理解しなくて良い気がします(汗
非常に簡単に片付けると文字列を入力する際には「&」が不要って事で今は良いと思います。
多分不味いですけど、ここを深く掘り下げると理解不能になると思いますしね…。
どうしても理解しておきたいという方はこのブログのブックマークにある
プログラミング解説サイトを参考にするのがいいと思います。
まぁコメント、メールにて質問して頂ければできる範囲で答えますが、説明し辛いんですよ…。

さて、次にいきます。「9文字以内で文字列を入力してください(半角英数のみ)」という部分
しかし今までの流れから考えると
a[0]~a[9]に整数を格納できていたように10文字分格納できそうなものです。
これはprintf関数の%sで表示したりする際に正しく表示するためにはどうしても9文字。
つまり、a[n](nは自然数)と仮定すると、(n - 1)文字までしか文字を格納できません。
ただ、これは%sの場合です。%cのみで表示するならn文字まで格納できます。
また、半角英数のみとありますが、別に全角の文字も入力できます。
まぁこの場合は9文字入力はできないので今回は止めておいて下さい(UU)

何故%sの場合(n - 1)文字なのかというと、n文字目。
つまり今回の場合だとmojiretu[9]の位置にはヌル文字(\0)というものを格納する必要があるためです。
かつて\nなどを紹介した第四章でちらっと書きました。
実はprintf関数は文字列を表示する際、ヌル文字を見つけるとそこで表示を止めます。
まぁ少しずつゆっくりとソース、実行結果を載せて紹介します。






ソース
array08
実行結果
array09


まずはヌル文字を見つけると表示が止まるという事を示しました。
ダブルクォーテーションで囲んだ場合、文字列の最後には勝手にヌル文字が付いてくれます。
この「ヌル文字を見つけると表示が止まる」という性質は重要です。






ソース
array10
実行結果
array11


… ずいぶんと縦に長々しくなりました(汗
さて、今回は1文字ずつ書いてみました。 この書き方もまた初期化時のみ有効です。
まぁこういう書き方もあるといった程度で十分ですけどね。
自分でヌル文字を入れないといけないわけですし。
mojiretu1の方は最後にヌル文字を入れ、mojiretu2の方は入れませんでした。
結果を見てみるとmojiretu1の方は正しく表示されています。(ヌル文字は画面に表示されません)
しかしmojiretu2の方は何か@が付いてますねぇ。 これはプログラムの開発環境によって変動するので
皆さんはおそらく違う結果が出ていると思います。 まぁ結局はバグるんですけど^^;

下には%cで表示した場合を載せました。
この場合は最後にヌル文字を入れる事は必要ありません。
mojiretu1の最後の所はヌル文字を表示していますが
画面に表示されないので何だか2回改行されているようにすら思えますね…。

要素数の省略



話は変わりますが、配列の要素数は実は省略する事ができます。
これはあらかじめ出力する文字列が決まっている場合
例:nagaimojiretuwosyuturyokusitemimasyou

… 何文字だか数える気が正直起きません。
こういう時省略する事ができるというのが便利ですね。
上の例だと char mojiretu[] = "nagaimojiretuwosyuturyokusitemimasyou";と書けます。
まぁこれはあらかじめ決まっている場合には有効です。 これも初期化時のみ有効です。
しかし、文字列をscanf関数で入力する場合には省略はできませんので気をつけて下さい。
つまり初期化する場合のみ省略ができます
これはint, doubleのような整数、実数型の配列でも可能です。
もちろんこの場合も初期化時のみ省略可能ですが。 int a[] = {1, 2, 3, 4, 5, 6}; こんな感じです。

scanf関数の危険性



ここまで解説してきましたが実際scanf関数でchar型の配列に入力するというのは危険です。
理由は入力する文字数の制限が確実でないからです。
例えば9文字までだと「%9s」と書けば制限できますが、「%s」では制限できません。
そもそも何か数字つけるとか忘れやすいですしーー;
まぁ%sでは、配列の要素数が10だろうと100文字、1000文字。
いや、何文字でも入力する事ができてしまいます。
これはクラッカーとかそういう人たちにシステムを破壊される原因となる部分の1つですので
バグが起こりやすいどころじゃすみませんね(汗
最初にバグが起こりやすいってかいたのはこのためでもあります。
それにscanf関数では空白を終了とみなす性質(言い方は正しくないと思われますが)
があるために入力文字の中にスペースやTabがあるとヌル文字があったかのようになってしまいます…。

array12

↑ こういうことです。 すでに試した方もいるかもしれませんね。

まぁそういうわけですのでこれでは名前をローマ字で打つ際などでもShinzo Abe
とかやるとShinzoしか表示されません。 これでは正直不味いです。
次回の章では入力文字数の制限ができるキーボードからの入力を受け取り、空白も問題ない関数を紹介します。
配列はまだまだ紹介しきれてませんがこの危険性を放置するわけにはいかないので…。

まとめ









{ }や""(こちらはchar型配列のみ)は初期化時のみ有効
文字列の入力の際には「&」をつけない
%sで表示する場合にはa[n]とすると(n - 1)文字までしか文字を格納してはいけない
初期化時のみ要素数の省略ができる
scanf関数は危険性を含んでいる


ここまで来たらこの第十九章は終了です。
とりあえず今回は例題は無しにしておいて、二十章で新しい入力関数を解説した後に
例題を出すことにします。 今現在の状態で例題とかやると
バグって面倒な事になるかもしれませんし…。
ここに書いてあることが分からない場合は





お気に入りの記事を「いいね!」で応援しよう

最終更新日  2007.04.23 12:34:27
コメント(0) | コメントを書く


PR

キーワードサーチ

▼キーワード検索

プロフィール

giru0116

giru0116

カレンダー

お気に入りブログ

まだ登録されていません

コメント新着

かほほほほ@ Re:ネイピア数(02/16) やっと見つけました! さがしていたので嬉…
通りすがり@ 見つけた! 円周率は結構載ってるんですが、 自然対…
無料@ アクセス記録ソフト 無料 楽天 アクセス記録ソフト! http:/…
無料@ アクセス記録ソフト 無料 楽天 アクセス記録ソフト! http:/…
無料@ アクセス記録ソフト 無料 楽天 アクセス記録ソフト! http:/…

フリーページ

ニューストピックス


© Rakuten Group, Inc.