0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

この記事について

「C言語の基礎を学ぼう」をテーマに、自身の知識 + α をアドベントカレンダーにまとめます。
25日間でC言語をマスターしよう - Qiita Advent Calendar 2025 - Qiita

こんな方を対象としています

  • コンピュータがプログラムをどのように動かしているか知りたい/知らない方

  • プログラミングをしてみたい方

  • C言語初心者の方

キーワード

  • 文字列

  • 文字列リテラル

説明

文字列

文字列の扱い方には2通りの方法があります。

  • char型の配列

  • 文字列リテラル(定数)をポインタで管理

#include <stdio.h>
int main(void) {
    // 宣言と同時に配列を初期化する場合、要素数を省略可能
    char str1[] = "test1";
    char *str2 = "test2";
    printf("%s\n", str1); // アドレスを渡す
    printf("%s\n", str2); // アドレスを渡す
    return 0;
}
test1
test2

文字列リテラルをポインタで管理した場合、 読み取り専用 となります。
文字列を変更することはできません。

文字列をchar型の配列で表現したとき、配列がどのようになっているかを見てみましょう。

#include <stdio.h>
int main(void) {
    char str[] = "test";
    int i = 0;
    // 配列全体のサイズを要素1つのサイズで割る = 要素数
    int e = sizeof(str) / sizeof(str[0]);
    printf("要素数:%d\n", e);
    for (i = 0; i < e; i++) {
        printf("%c\n", str[i]);
    }
    return 0;
}
要素数:5
t
e
s
t

test という4文字の文字列を配列に入れた際、配列のサイズは 5 になります。
表示上は何も見えていませんが、配列の5要素目には ヌル文字( \0 が格納されます。

配列の要素数を明示的に指定する場合は、 文字列の長さ + 1 を確保するように気を付けましょう。

文字列は 先頭からヌル文字までのメモリの値 です。
プログラムで確認してみます。

#include <stdio.h>
int main(void) {
    char str1[] = "test1";
    char str2[] = {'t', 'e', 's', 't', '2', '\0'};
    char str3[] = {'t', 'e', '\0', 's', 't', '2', '\0'};
    printf("%s\n", str1);
    printf("%s\n", str2);
    printf("%s\n", str3); // ヌル文字まで表示
    printf("%s\n", &str3[3]); // 途中のアドレスから表示
    return 0;
}
test1
test2
te
st2

練習

1. シーザー暗号

任意のアルファベット大文字のみの文字列をシーザー暗号文にしてみよう。

STORY
VWRUB

ポイント

シーザー暗号とは下記のような暗号です。

  • 文字列を1文字ずつ分けて考えます。

  • 文字をアルファベット表で任意の数ずらします。

  • 例えば3ずらす場合、A → D 、B → E 、C → F 、・・・、Z → C、となります。

ASCIIコードの性質を利用して、文字を数値に変換してから計算するとよいです。

解答例

#include <stdio.h>
int main(void) {
    char str[] = "STORY";
    int i;
    printf("%s\n", str);
    for (i = 0; str[i] != '\0'; i++) {
        str[i] = 'A' + ((str[i] - 'A' + 3) % 26);
    }
    printf("%s\n", str);
    return 0;
}
STORY
VWRUB

2. UUID

ランダムなUUIDを作成しよう。

7e14cc24-368b-6bfc-5e59-341d01507e668

ポイント

UUIDとは下記の形式です。

  • 形式:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

  • xは16進数( 0 ~ f )が入ります。

16進数を文字列に変換する際には sprintf が便利です。
printf と同様の引数に加え、先頭に格納先のアドレスを指定します。

sprintf(格納先charのアドレス, "任意の文字列"....)

ランダムな値は疑似乱数を利用します。

#include <stdio.h>
#include <stdlib.h> // srand()、rand()に必要
#include <time.h> // time()に必要
int main(void) {
    int r;

    // 疑似乱数生成準備としてシード値を設定する。
    // シード値にはプログラム実行時刻を用いることが多い。
    // (実行ごとにランダムにするため)
    srand((unsigned int)time(NULL));

    // rand()で乱数を生成する。
    // 生成した値を加工して欲しい乱数にする。
    r = rand();

    printf("%d", r);
    return 0;
}

解答例

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
    char uuid[37];
    int i;
    srand((unsigned int)time(NULL));
    for (i = 0; i < 37; i++) {
        if (i == 8 || i == 13 || i == 18 || i == 23) {
            uuid[i] = '-';
        } else if (i == 37) {
            uuid[i] = '\0';
        } else {
            sprintf(&uuid[i], "%x", rand() % 16);
        }
    }
    printf("%s", uuid);
    return 0;
}
7e14cc24-368b-6bfc-5e59-341d01507e668

UUIDは、重複しないIDとしてよく使われます。

おわりに

文字列は配列であるという考え方は大切です。文字列の配列を作成する場合は2次元配列のような形式になります。

文字列を変更しようとしてうまくいかない場合は、文字列リテラルになっていないか確認するとよいです。

参考文献

↓↓↓ はじめてプログラミングを学んだときに読んだ本です ↓↓↓
詳細(プログラミング入門 C言語)|プログラミング|情報|実教出版

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?