文字列リテラル中のナル文字
C言語勉強会にて、char の配列の途中に\0をセットすると文字列としてはそこで終端されると説明した。ある人が次のようなコードを試した。
char str[] = "0123456\0789"; /* 元々は"0123456789" */ printf("%s\n", str);
コンソールに
0123456
と表示されると思っていたのだが表示されたのは
012345689
だった。7はどこへ?
文字定数として\oooは8進数を表すただしoooは2桁もしくは3桁の8進数である。パーサは解釈できる最長のものをトークンとするので\07までを一つの文字定数として解釈する。078は8進数としては解釈できない。
以下検証用のコード
#include <stdio.h> int main(void) { /* 下記は次の宣言と同等の意味。簡単にかけるようになっている str1の宣言は次と同等(コンパイラは下記のように解釈している) char str1[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0'}; */ char str1[] = "0123456789"; /* str2の場合は以下と同等 char str2[] = {'0', '1', '2', '3', '4', '5', '6', '\07', '8', '9', '\0'}; */ char str2[] = "0123456\0789"; int i; printf("----- str1の場合 ---------\n"); printf("%s sizeof(str1): %d\n", str1, sizeof(str1)); for (i = 0; i < sizeof(str1); i++) { printf("%d文字目 %c コード %#x\n", i, str1[i], str1[i]); } printf("----- str2の場合 ---------\n"); printf("%s sizeof(str2): %d\n", str2, sizeof(str2)); for (i = 0; i < sizeof(str2); i++) { printf("%d文字目 %c コード %#x\n", i, str2[i], str2[i]); } return 0; }