「C言語」の「入力機能」の使い方を学ぶ
ほとんど忘れている「C言語」に再入門してみて思ったことは、「2回目の学習だからといって、学習は全然簡単じゃない」ということ。
学ぶ内容は変わっていないので、考えてみれば「当たり前」なのですが、自分が成長できていないことをあらためて実感しました。
ということで、今回も「C言語」の機能について学んでいきたいと思います。
ただの「プログラミング学習記録」ですが、読んで楽しんでもらえたら嬉しいです♪
「入力」機能の作り方と「メモリアドレス」
これまでは、「変数」「データ型」などを学んで、単純な計算ができるプログラムを作ってみましたが、「変数」にあらかじめ入れておいた値の計算ができなかったので、「電卓」みたいに自分で入力した値の計算ができる方法がないかといろいろと調べていきました。
値の入力できる関数がいくつか見つかったのですが、この関数の違いがよくわからない。
- scanf
- sscanf
- fgets
どれも同じような機能を持っていて、どれを使っていいのか判断ができないので、調べながら学んでいきたいと思います。
「scanf」関数の使い方
まず、「scanf」は
「フォーマット」を元に値を入力することができて、入力されたキーボードの値を「8・10・16進数」で入力ができたりするそうです。
では、実際に試してみたいと思います。
#include <stdio.h> int main(void) { int i; scanf("%d",&i); printf("入力した値は「%d」です。", i); return 0; }
このコードを実行した際に「数値」を入力すると、入力した値が表示されるようになります。
2 入力した値は「2」です。
ただし、「%d」は数値で入力を受け付けるので、数値以外の値を入力すると、「0」になります。
a 入力した値は「0」です。
ということは、数値を扱いたい場合は、数値がきちんと入力されているのかを調べる必要があります。
プログラムを書いて実行しているといろいろと学べることが多いですね。
メモリアドレス
「scanf」関数の第一引数に「受け取る値の変換指定子」を書き、第二引数にはデータを格納する変数の「アドレス」を入力します。
「ん?アドレス?」ってなったのですが、「変数が用意されているメモリアドレス(メモリ番地)」を指定するそう。
「scanf」関数の第二引数に指定した「i」の変数の前に「&」がありましたが、この記号は「アドレス演算子」と呼ばれるそうで、「メモリアドレス」を取得するための演算子です。
「メモリアドレス」は、コンピュータ内にデータを保存することができる「メモリ」と呼ばれる「記憶装置内」で割り当てられているデータの保存先を表す「住所」のようなものです。
「メモリ内の区画」ごとに「メモリアドレス」が割り当てられていて、「変数」もこの「メモリ内の区画」に割り当てられているため、「変数」を表す「メモリアドレス」が存在しているんですね。
なんか複雑な仕組みだな~とずっと今も思っています(^_^;)
あとでしっかり勉強しよう。
ちなみに変数の「メモリアドレス」を表示するプログラムは、
#include <stdio.h> int main(void) { int i; scanf("%d",&i); printf("入力した値は「%d」です。", i); printf("変数iのメモリアドレスは「%p」です。", &i); return 0; }
のようになります。
「メモリアドレス」を表示するための「変換指定子」は「p」となっていますね。
今回は「メモリアドレス」を表示するため変数名の前に「&」を付けることが必要です。
このプログラムを実行すると、
2 入力した値は「2」です。変数iのメモリアドレスは「000000000061FE4C」です。
と表示されます。
2つの変数を利用して、1回ずつメモリアドレスを表示するプログラムを作ってみたのですが、想定とは違い、2つの値を入力した後で無いと、「メモリアドレス」が表示されませんでした。
#include <stdio.h> int main(void) { int i; int j; scanf("%d",&i); printf("入力した値は「%d」です。", i); printf("変数iのメモリアドレスは「%p」です。", &i); scanf("%d",&j); printf("入力した値は「%d」です。", j); printf("変数iのメモリアドレスは「%p」です。", &j); return 0; }
このプログラムを表示すると、
1 2 入力した値は「1」です。変数iのメモリアドレスは「000000000061FE4C」です。入力した値は「2」です。変数iのメモリアドレスは「000000000061FE48」です。
と表示されます。
でも、なんで、上から順に実行されてるはずなのに、2つ値を入力しないと表示ができないのが、今だに謎・・・
また後で、原因を調べてみたいと思います。
「sscanf」関数の使い方
「sscanf」関数は、「文字列」が格納された変数等から入力を受け付けるための関数です。
例えば、
#include <stdio.h> int main(void) { int year; int month; int day; char date[32] = "2019 1 1"; sscanf(date,"%d %d %d", &year, &month, &day); printf("年の値は「%d」で、月の値は「%d」で、日の値は「%d」です。", year, month, day); return 0; }
というプログラムを実行すると、
年の値は「2019」で、月の値は「1」で、日の値は「1」です。
のように表示されます。
「sscanf」関数の第1引数には、「文字列のデータ」を指定し、第2引数には、「書式指定文字列」を書き、第3引数以降は「書式に基づいて値を格納する変数」を指定していきます。
どのようなケースでこのプログラムを使うんだろう・・・
「fgets」関数の使い方
「fgets」関数も「scanf」関数と同様にキーボードの入力を受け付けることができます。
「fgets」関数を使用したプログラムは、
#include <stdio.h> int main(void) { char input[100]; fgets(input,sizeof(input),stdin); printf("入力された文字は「%s」です。", input); return 0; }
となります・・・が、実行すると、
a 入力された文字は「a 」です。
のように出力されてしまいます。
せっかく文字を入力したのに、なぜか改行されてる・・・
入力した文字は「配列」に格納されているのですが、「最後の要素」に改行文字が入っているらしく、これを削除する必要があります。
改行を削除するプログラムは、
配列変数名[strlen(配列変数名) - 1] = '\0';
のようになります。
「改行の削除」入れた完成コードは、
#include <stdio.h> int main(void) { char input[100]; fgets(input,sizeof(input),stdin); input[strlen(input) - 1] = '\0'; // 最後の改行を削除 printf("入力された文字は「%s」です。", input); return 0; }
のようになります。
このプログラムを実行すると、
a 入力された文字は「a」です。
のように改行が削除されて入力した文字が表示されます。
ふ~。今回は入力機能を中心に学んできましたが、思ったほど簡単にはいきませんでした。
でも、また一つ成長できた気がします。
もっともっとC言語のいろいろな機能を学んで何かアプリケーションを作れるようになりたいと思います。