LoginSignup
0
0

More than 1 year has passed since last update.

【C】初めてのC言語(17. 文字列リテラル)

Posted at

はじめに

学習環境

  • 今回はpaiza.ioのC言語のエディタを使いました。

文字列リテラルの機能

  • ダブルクォーテーションで囲まれた文字列(文字列リテラル)は、自動的に末尾に「\0」を付ける処理が入っています。
    • ダブルクォーテーションを使わず、char型の配列として文字列を作る場合は終端文字として「\0」を入れます。
  • 以下のコード中の3つの配列(str1~str3)は全く同じ内容の文字列(Hello)を表しています。
Main.c
#include <stdio.h>

int main(void){
    const char str1[10] = "Hello";
    const char str2[10] = {'H', 'e', 'l', 'l', 'o', '\0'};
    const char str3[10] = {72, 101, 108, 108, 111, 0};
    
    printf("%s\n", str1);
    printf("%s\n", str2);
    printf("%s\n", str3);
    
    return 0;
}
実行結果
Hello
Hello
Hello

文字列宣言でよくある誤り

  • 以下のように、「n文字を格納するために用意する配列の要素数がn(=nバイト)」だと、最後に「\0」を入れる要素が足りなくなってしまいます。
Main.c
#include <stdio.h>

// よくある誤り
int main(void){
    const char str[5] = "Hello";  // 配列の要素数が「文字列の長さと等しい」と、終端文字を入れられない!
    printf("%s\n", str);
    return 0;
}
  • そのため、次のように「配列の要素数を文字列の長さ(バイト数)+1(=n+1バイト)」にする必要があります。
Main.c
#include <stdio.h>

// 誤りを修正したコード
int main(void){
    const char str[6] = "Hello";  // 配列の要素数は「文字列の長さ(バイト数)+1」
    printf("%s\n", str);
    return 0;
}
  • あるいは要素数を省略して、char 変数名[] = "初期値"という形で宣言すれば、「\0」を含めた必要な要素数が自動的に確保されます。
  • そのため、文字列宣言時のオーバーランを防ぐことができます。
Main.c
#include <stdio.h>

int main(void){
    const char str[] = "Hello";
    printf("%s\n", str);
    return 0;
}
  • 一方で、char 変数名[] = "初期値"という形で宣言して防げるのは「文字列宣言時のオーバーラン」だけなので、以下のように長い文字列で上書きするとオーバーランが発生してしまいます。
  • そのため以下の例では、memcpyによるコピー先(※ここではstr1)で確保されているメモリ領域を確認しておく必要があります。
Main.c
#include <stdio.h>

int main(void){
    char str1[] = "Hello";
    char str2[] = "Hello,world!";
    memcpy(str1, str2, 13);  // 長い文字列で上書きはNG
    return 0;
}

参考URL

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