【C言語】
文字列が空かどうか終端文字¥0を使って判定する方法

■この記事の概要

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