■この記事の概要
C言語での空文字列判定において、NULLポインタと終端文字¥0を正確に区別する方法を解説。
安全性を重視した推奨例と、避けるべき非推奨例を示し、プログラムの安定性を向上させます。
■NULL判定って書くのは止めよう!
【NULL判定】
【ヌル判定】
【ナル判定】
って書くのは止めよう!
【NULLポインタ判定】
【空文字列判定】
【終端文字¥0判定】
と書こう。
■NULL判定と書くとバグります
#include <stdio.h>
char *Empty(char *str){
if(str[0] == NULL){//NULL判定
return "空文字列";
}
return str ;
}
int main(void) {
puts(Empty("ABCD"));
puts(Empty(""));
puts(Empty(NULL));
}
上記のコードはNULLポインタと終端文字¥0の区別がついていない
初級者の間違いです。
一文字のstr[0] と NULLポインタを比較していますが
NULL判定と書くと、初級者の方は
NULLポインタのチェックをしているのか
NULL文字’¥0’のチェックをしているのか
混乱してしまうようです。
●コンパイル実行結果(バグった例)
+ gcc f1.c
f1.c: In function ‘Empty’:
f1.c:3:15: warning: comparison between pointer and integer
3 | if(str[0] == NULL){//NULL判定
| ^~
+ ./a.out
ABCD
空文字列
Segmentation fault (core dumped)
筆者のlinux環境下ではSegmentation faultで異常終了してしまいました。
■C言語では空文字列””との直接比較はできません
#include <stdio.h>
char *Empty(char *str){
if(str == ""){
return "空文字列";
}
return str ;
}
int main(void) {
puts(Empty("ABCD"));
puts(Empty(""));
puts(Empty(NULL));
}
上記のコードは
if(str == “”)のところで
一見初級者の意図した動きをする事がありますが
これはたまたまです。
この比較は空文字列の比較ではなくて、
文字列のアドレス比較を行っています。
詳しくはこちら。
■空文字列を判定する推奨方法
#include <stdio.h>
char *Empty(char *str){
if(str == NULL) {
return "NULLポインタ";
}
if(str[0] == '\0') {
return "空文字列";
}
return str ;
}
int main(void) {
puts(Empty("ABCD"));
puts(Empty(""));
puts(Empty(NULL));
}
NULLポインタと終端文字¥0、
NULLポインタと空文字列””を
しっかり区別した書き方です。
●コンパイル実行結果
+ gcc f3.c
+ ./a.out
ABCD
空文字列
NULLポインタ
参考:
C-FAQ5.13: “ヌル”とか”NULL”とか”ナル”という単語が無造作に使われるときは以下のどれかを意味する。
http://www.kouno.jp/home/c_faq/c5.html#13