C言語⑭(2025/07/09)

文字列変換関連の関数

●sprintf_s()…数値などを文字列に変換する(指定されたバッファ領域に作成した文字列を格納する)

sprintf_s(buffer, format, augment);
[buffer]:作成した文字列を出力するバッファ(ポインタで指定)
[format]:書式付きの指定文字列
[augment]:(省略可能)

char buff[100];

sprintf_s(buff, "文字列作成(%f)テスト\n", 120.5);  //配列buff[]に、""で囲んだ内容を格納

printf(buff);

実行結果

文字列作成(120.500000)テスト

エラーコードなどを表示する際に、なんらかの条件に応じて文字列を生成し、結果をまとめて表示したい場合などに使う。なお、生成したい文字列のサイズに合わせてbuffを確保しておくこと。

※OutputDebugString()
文字列を表示できるが、printfと違い、変数などの組み合わせができない。
このため、事前に文字列を合成して表示させる、という手法が良く使われる。

#ifdef _DEBUG
//この中に記載したものは「デバッグモード」でビルドした場合のみ含まれる。
  //「リリースモード」でビルドした場合には含まれない。
#endif

●atoi()、itoa()…文字列(数字)を数値に、数値を文字列(数字)に変換する

atoi(str)
[str]:変換対象の文字列
(戻り値):入力文字列を数値と解釈して生成されるint型の値
     入力をその方の値に変換できない場合は”0”を返す

	int val = atoi("120");
	printf("%dをatoiで変換した結果:%d\n", 120, val);

実行結果

120をatoiで変換した結果:120

_itoa_s(value,buffer,radix);//⇒(変換元、変換先、基数)
※変換元[value]:
※変換先[buffer]:変換結果を格納するバッファ(ポインタで指定)
※基数[radix]:2進数、8進数、10進数、16進数など。2~36まで。

#include <stdlib.h>
char buff[100];

int val = atoi("255");
printf("atoiで変換した結果 = %d\n", val);
_itoa_s(val, buff, 16);
printf("itoaで変換した結果 = %s\n", buff);

実行結果

atoiで変換した結果 = 255
itoaで変換した結果 = ff

あなた:atoi と itoa って、10進数の数字⇔数値の変換をやるだけってことでいいですか?

Copilot:いい質問ですね!結論から言うと、atoi()itoa() は「文字列 ⇔ 数値」の変換を行う関数ですが、10進数に限らず使えるケースもあります

🔁 atoi() の役割(文字列 → 数値)

  • atoi()文字列を整数(int)に変換します。
  • 入力される文字列は 基本的に10進数表記である必要があります。
  • 例:

int value = atoi(“1234”); // → value = 1234

📌 注意点

  • atoi()非数値文字が混ざっていると途中で変換を止める
  • "12abc"12 に変換される。
  • "abc"0 に変換される(エラー検出はできない)。

🔁 itoa() の役割(数値 → 文字列)

  • itoa()整数を文字列に変換します。
  • 第3引数で 基数(radix)を指定できるのが特徴です。
  • つまり、2進数・8進数・16進数・36進数などにも対応できます。

✅ まとめ

関数名方向基数の扱い備考
atoi()文字列 → 数値10進数のみ非標準文字は無視される
itoa()数値 → 文字列2〜36まで指定可能非標準関数(環境依存)

あなた:数値の文字=数字という含意だったのですが。それを踏まえたらどういう説明になりますか?

Copilot:なるほど、ゆきさんの「数値の文字=数字」という含意を踏まえると、atoi()itoa() の説明も少し視点を変えて整理できますね。

🔄 数値 ⇔ 数字(文字)の変換という観点で見ると…

関数名変換の方向入力出力含意
atoi()数字(文字)→ 数値"123"(文字列)123(int型)数字を数値として解釈する
itoa()数値 → 数字(文字)123(int型)"123"(文字列)数値を数字として表現する

ここでいう「数字」は、**数値を表す記号(たとえば ‘1’, ‘2’, ‘3’)であり、「数値の文字」**という表現はまさにこの意味にぴったりです。

🧠 もう少し踏み込むと…

  • 数値(value) は「意味を持つ量」や「計算可能な実体」。
  • 数字(digit / numeral) は「その数値を表す記号」。
  • atoi() は「数字を読んで意味を取り出す」。
  • itoa() は「意味を記号に変換する」。

つまり、atoi() は「記号を意味に変換」し、itoa() は「意味を記号に変換」する、という双対的な関係にあります。

✨ ゆきさんの含意を活かしたまとめ

atoi()itoa() は、**「数値の文字(=数字)」と「数値そのもの」**の間を行き来する関数である。

この視点は、C言語の型変換や文字コード処理を学ぶうえでも非常に本質的です。たとえば '3' は ASCII コードで 51 ですが、'3' - '0' で 3 という数値に変換できるのも、まさに「数字=数値の文字」という含意があるからこそですね。


多次元配列
1次元配列 int[a]
2次元配列 int[a][b]
3次元配列 int[a][b][c]



※二次元配列

int Array[x][y];
もちろんです、ゆきさん!
int Array[x][y]; は、2次元配列(二重配列)を宣言する構文です。これで、整数型(int)のデータを格納する表のようなデータ構造を作れます。

📦 構文の意味
int Array[x][y];
- int:この配列が整数 (int) を格納することを示します。
- Array:配列の名前です。自由に名前をつけられます。
- [x][y]:それぞれのインデックス(添え字)
- x は行数(縦方向)
- y は列数(横方向)
たとえば int Array[3][4]; なら、3行4列の配列 → 合計 12個の int 値が格納できます。

🎯 使い方例
#include <stdio.h>

//初期化付宣言
int main() {
    int Array[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };

    printf("%d\n", Array[1][2]);  // 結果: 6(2行目3列目の値)
    return 0;
}

💡補足ポイント
- Cでは配列のインデックスは0から始まるため、Array[0][0] が最初の要素になります。
- Array[x][y] という宣言は、x 行、y 列の“固定サイズの表”を作る感覚です。
- 動的にサイズを変えたい場合は、ポインタと malloc() を使った動的2次元配列にする必要があります(少し高度ですが、興味があれば解説します!)

📊 例:int Array[3][4]; のイメージ

行\列0列1列2列3列
0行Array[0][0]Array[0][1]Array[0][2]Array[0][3]
1行Array[1][0]Array[1][1]Array[1][2]Array[1][3]
2行Array[2][0]Array[2][1]Array[2][2]Array[2][3]

この配列は「3行4列」の構造を持ち、全部で 3×4=12個int 型のデータを格納できます。

🔍 ポイントまとめ

  • が先、が後 → Array[行][列]
  • 配列のインデックスは 0から始まる
  • 表形式で管理できるので、ゲームの盤面やデータテーブルなどに便利

(by Copilot)

初期化について
要素数が少ない場合、

int a[2][3] = {
    { 10, 20, 30},
    { 40, 50, 60}
};

のように記載してもよいが、要素数が増えた場合には手間がかかる上に間違う可能性もあるので
規則的な場合にはfor文で値を入れてゆく方が効率的。

int a[2][3]; // 2行3列の配列を定義

int value = 10;
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        a[i][j] = value;
        value += 10;
    }
}

memset などで、全ての要素を決まった数で初期化する、などの方法もある。

memsetメモリ領域に特定のバイト値を一括で書き込む関数で、
C言語で「配列をすべて同じ値で初期化したい」ときにめちゃ便利です。


✅ 基本構文

#include <string.h> // memset を使うときはこれをインクルード

memset(配列の先頭ポインタ, 書き込む値(1バイト), 書き込むバイト数);

✅ 具体例

#include <string.h>

int a[6];
memset(a, 0, sizeof(a)); // a[0]~a[5]をすべて0に初期化

このように sizeof(a) を使うことで、配列全体に 0 を入れられます。


⚠ 注意点!

ここ重要です:

memset1バイト単位で値を埋める関数です。

なので、たとえばこうすると危険:

cコピーする編集するmemset(a, 1, sizeof(a)); // NGではないけど注意!

これは「配列全体に 0x01(1バイト値)を埋める」という意味なので、
int 型(4バイト)が全部 0x01010101 になり、
a[0] の中身が 16843009 になります(びっくりでしょ?笑)


✅ よくある用途

  • memset(配列, 0, sizeof(配列));
    配列全体を 0 で初期化する(超定番)
  • memset(構造体ポインタ, 0, sizeof(構造体));
    → 構造体のメンバー全部を一括で初期化

🧠 まとめ

目的方法備考
配列や構造体を全部0にしたいmemset(ptr, 0, size);安全・高速・簡単
0以外の値を入れたい基本は for文で入れるmemsetは1バイト単位なので注意

✨覚えておいて損なし!

memset(配列, 0, sizeof(配列));
C言語の“定型句”のひとつです!


コメント

タイトルとURLをコピーしました