[C言語 #2]scanf関数

## はじめに
こんにちは
今回はC言語#1で作成したコードの解説から入りたいと思います。
その後はprintf関数以外にscanf関数について簡単に解説いたします。
## 前回のおさらい
前回#1の最後辺りで文字を表示させるだけのコードを作成いたしました。
```c
#include <stdio.h>	
int main(void)
{	
	printf("C言語へようこそ\n");	
	return 0;
}
```
そして実行するとこのような画面が表示されることを確認いたしました。
![スクリーンショット 2024-06-10 092205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/2dfe65b3-46e8-329d-eba1-ceab7e706ac4.png)
ではここからこのコードについて1行ずつ解説いたします。
## コードの解説
コードの中に**大まかな解説**を入れましたのでご覧ください。
```c
// ここにプログラムを書いていきます。


//「//」「/**/」はコメントアウトという意味です。プログラムには反映されません

#include <stdio.h>	// 標準C言語ライブラリです。これがないとprintf()が使用できません。

/**************************************************************************************
	C言語で書かれたプログラムは、まず「main関数」から実行されることになっています。
	「int main(void){」から始まり「}」までが「main関数」です。
***************************************************************************************/
int main(void)
{
	/***************************************************************
	   「printf」という名前の関数を使用します。
		この関数を使用することで実行時に入力した文字が表示されます
		書式：printf("「入力したい文字」");
	****************************************************************/	
 
	printf("C言語へようこそ\n");	

	/***********************************************************************************
		「return 0;」は簡潔に言うと「main関数を終了させる」という意味です。
		「main関数」が終了するとプログラムも終了することになっています。
		 その結果、「return 0;」と言う行が実行されるとプログラムが終了します。
	************************************************************************************/
	return 0;
}
```
## コードの補足
```c
#include <stdio.h> // includeは「含める・入れる」という意味です。
```
・stdio.h ->「.h」は**ヘッダーファイル**を意味します。

### ヘッダーファイル
<font color=red>**関数などの宣言のみを記したファイル**</font>です。ヘッダーファイルは他にも
**math.h（数学系関数）**、**stdlib.h（ライブラリ）** など沢山あります。

stdio.hは**入出力系のヘッダーファイル**です。**printf()は出力系の関数**です。つまりこのヘッダーファイルを**含めないと**このprintf()というのは**使えない**ことになります。なので記載されてないとエラーが出てしまうので注意です。:expressionless:

因みにstdioとは「(std)**standard** (i)**input**/(o)**output**（標準入出力）」の略称です。
stdlibなら「**standard library**（標準ライブラリ）」の略称になります
```c
int main(void)
{
    return 0;
}
```
・「int」は**整数型**を表してます。この関数を実行すると何かしらの整数値が返ってきます。
・「main」は**関数**を表してます。サンプルコードは関数が1つだけなで関数名が「main」になります。
・「void」は**引数**が無い場合に使います。「この関数は引数を取らないすな」という意味です。なので…
```c
int main()
{
    return 0;
}
```
このように「void」を省略しても良いですし
```c
void main()
{
    // void main()とする場合、返り値return 0;は不要
}
```
このように記載する方法もあります。しかしvoid main()は正当な使用方法があまりないため予期せぬエラーや無効な値が返ってくることがあります。あまり良い方法ではありませんがこういう書き方もできるのかぁで良いと思います。
[void main()と書いても良いのか？](https://www.geeksforgeeks.org/is-it-fine-to-write-void-main-or-main-in-c-cpp/)


## scanf()
先ほどはstudio.hを入れないと入出力系の関数が使えないのです～というように解説しました。printf()は出力系の関数でしたが**入力系の関数にscanf()（スキャンエフ）** というものがあります。:keyboard:

scanf関数を使うと**キーボードで文字や数値を入力することができます**。
しかしscanf関数は書式が必要なため**変数**というものを指定しなければなりません。
### 変数
**値を入れるための箱**を変数と言います。:gift:
コンピュータの頭脳であるCPUは、計算などの処理をしても、その結果をメモリ（記憶領域）に入れておかないとすぐに**忘れてしまいます**。ですので、計算結果などは変数(メモリ領域)に入れて利用します。

また変数は、名前を付けることができます（変数名）
![スクリーンショット 2024-06-12 093203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/fbafee9a-3b0d-e160-bf74-aaa6bb19cff5.png)
そして変数を使うには宣言が必要です。
あらかじめコンピュータに「変数を使います」と伝える処理です。
宣言されてない変数を使おうとするとエラーになります。

ではscanf関数に戻って…
図のようにscanf関数の書式は、printf関数のときと同じように、**書式指定子**によって用意した変数にどんなデータを代入するのか指定します。
![スクリーンショット 2024-06-12 093851.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/cad9936c-7f63-dd2a-f125-0f59045f3050.png)
しかしscanf関数はprintf関数と違って、変数の**アドレス**を指定しなければなりません。
そのために**アドレス指定子「&」をつけます** ←<font color=red>**重要です**</font>

### 書式指定子
ざっくりとよく使うものを紹介します。
printfでもscanfでも**適切に指定しないと正しく入力や表示ができない**ので注意！
[フォーマット指定子一覧表](https://www.k-cube.co.jp/wakaba/server/format.html)
| 書式指定子 | 意味 | 対応するデータ型 | 備考 |
|:-:|:-:|:-:|:-:|
| **%d** |**10進整数**|**int**|   |
| **%f** |**実数**|**float,double**|**double型変数に入力する時は%lfを使う**|
| **%c** |**文字**|**char (intなど)**|   |
| **%s** |**文字列**|**char型配列のアドレス（ポインタ）** |**scanfでは&をつけない**|
| %x |  16進整数 |  intやchar |   |
| %hd |   | short int  |   |
| %ld |   | long int  |   |
## scanfのサンプルコード
ではこれらの情報を活用してコードを作成してみましょう。
今回も超シンプルです。
```c
#include <stdio.h>	// 標準C言語ライブラリです。
int main()
{
	// 変数宣言.
	int number;    // intなので入力した数値はすべて整数値が返ってきます.

	// 入力処理.
	printf("\nキーボードで数値を入力してください：");
	scanf("%d", &number);

	// 表示.
	printf("入力した数値は%dです：\n",number);
 
	return 0;
}
```
では実行してみます。
![スクリーンショット 2024-06-12 102814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/92d45aa3-5325-a151-94d3-3b1378327cb2.png)
試しに100と入力します。
![スクリーンショット 2024-06-12 102857.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/cb399d5c-9230-8784-ed95-7f03289794cd.png)
正しく100が返ってきました。
ではint型の状態で文字や実数を入力した場合どうなるか試してみます。
![スクリーンショット 2024-06-12 103107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/4bfea67f-7999-a346-b253-055af655d0e8.png)
3.14と入力したら3と返ってきました。
そうですint型は**10進整数値を返す**ので小数点以下の部分は表示されません。
```c
float number;
scanf("%f", &number);
printf("入力した数値は%fです\n",number);
```
floatと%fに変更して再度実行してみましょう
![スクリーンショット 2024-06-12 104038.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/76f2387c-b28d-65be-d3f7-0d8b15d729cb.png)
これで正しく実数が表示されましたね！…でもなんか残りの0が気になりますね:thinking:
そんな時は…
```c
printf("入力した数値は%.2fです\n",number);
```
%fの間に.2を入れてみました。これで小数点以下第二位まで表示させます。
![スクリーンショット 2024-06-12 104611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/45930d8a-bf6e-24d4-e762-193f74f7ac9f.png)
因みに「%.1f」なら3.1となり「%.3f」なら3.140というように表示されます。
[小数点以下の扱いについてはこちら](https://x.gd/v5KF5)

今度は文字列で試してみます。
![スクリーンショット 2024-06-12 105026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/d48f1751-988c-574c-89ed-08430095482b.png)
int型は整数値が返ってくるので文字列は表示されないのが確認できます。
従ってintではなくcharと%cに変更します
![スクリーンショット 2024-06-12 105229.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/be71f86e-9f54-f925-87e9-28972e92a50b.png)
あれ、文字列は表示されましたが**1字だけ**ですね:rolling_eyes:
そうです。charで「%c」と指定した場合、返ってくるのは**文字列1字だけ**です。
なので複数表示したい場合は「%c」ではなく「%s」とします。
```c
// charを扱う場合に[字数容量]を指定します。膨大な量でないなら8や16、32や64辺りが無難です
char number[16];
scanf("%s", &number);
printf("入力した値は%sです\n",number);
```
![スクリーンショット 2024-06-12 110041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/4c731fa3-6baa-96ae-2d91-ced02301de43.png)
これで正しく表示されましたね。:upside_down:
## 因みに・・・
Visual Stdio内で下の方にこんな表示が出ているのを見つけました。
![スクリーンショット 2024-06-12 110804.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/55dbc93f-bbcf-b4c6-9f58-581478cd4a3d.png)
どうやらscanf("%d",&number);の部分で**警告**が出ているようです。
別にこのぐらいのコードで警告出てもほぼ気になりませんが…
一応対処方法があるので実施します。
```c
(void)scanf("%d",&number);
```
scanf関数の頭に **(void)を加えます**。
これで終わりです。
![スクリーンショット 2024-06-12 111720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/2a77923b-331c-0dfa-9551-4144af73af0a.png)
警告が消えたのも確認できました。

「void」は簡単に**値を無視する**という意味でした。
何も書かないと、そこに値があるのに気付かずに無視しているのかな？とコンパイラに思われてしまいます。**そこは分かってるけど見ないことにしていますよ**と言う、そういった意思表示で頭に(void)をつけることでこの警告は出なくなります。
## おわりに
入出力関数（printfとscanf）の仕組みについていかがだったでしょうか。
少しでもこの関数のイメージがつきましたら幸いです。
最後まで読んで頂きありがとうございました！
> **「サイト」**
[scanf関数の扱い方](https://www.sejuku.net/blog/24965)

> **「サイト」**
[C言語-プログラムの基本](https://webkaru.net/clang/int-main-void/)