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

文字列の終わりに 終端文字¥0

NULL判定って書くのは止めよう!

【NULL判定】
【ヌル判定】
【ナル判定】
って書くのは止めよう!

【NULLポインタ判定】
【空文字列判定】
【終端文字¥0判定】
と書こう。


■推奨例:空文字列を判定する関数

#include <stdbool.h>
#include <stdio.h>
bool    isEmptyString(const char  *p){
    if(p == NULL) {
        printf("NULLポインタ\t");
        return  true;
    }
    if(p[0] == '\0'){ 
        printf("空文字列\t");
        return  true;
    } 
    printf("有効文字列\t");
    return  false ;
}
int     main(void) {
    printf("%d\n",isEmptyString(NULL)); //NULLポインタ  
    printf("%d\n",isEmptyString(""));   //空文字列
    printf("%d\n",isEmptyString("有効文字列"));
}

NULLポインタと終端文字¥0、
NULLポインタと空文字列””を
しっかり区別しましょう。

■非推奨例1:いきなりstrcmp

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool    isEmptyString(const char  *p){
    if(strcmp(p,"") == 0) {
        printf("空文字列\t");
        return  true;
    }
    printf("有効文字列\t");
    return  false ;
}
int     main(void) {
    printf("%d\n",isEmptyString(NULL)); //NULLポインタ  
    printf("%d\n",isEmptyString(""));   //空文字列
    printf("%d\n",isEmptyString("有効文字列"));
}

引数のポインタが空文字列かどうか判定したい時、
strcmp()を使って第二引数にNULLポインタを渡してはいけません。
NULL参照が発生して
プログラムが異常終了してしまう可能性があります。


■非推奨例2:いきなりstrlen

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool    isEmptyString(const char  *p){
    if(strlen(p) == 0) {
        printf("空文字列\t");
        return  true;
    }
    printf("有効文字列\t");
    return  false ;
}
int     main(void) {
    printf("%d\n",isEmptyString(NULL)); //NULLポインタ  
    printf("%d\n",isEmptyString(""));   //空文字列
    printf("%d\n",isEmptyString("有効文字列"));
}

NULLポインタのチェックをしてからstrlen(p)を呼び出しましょう。

又、strlen(p) 関数を呼び出すため、
関数呼び出しのオーバーヘッド分プログラムの実行速度が
遅くなります。


■非推奨例3:NULLと’\0’の混乱

#include <stdbool.h>
#include <stdio.h>
bool    isEmptyString(const char  *p){
    if(p == '\0') {
        printf("NULLポインタ\t");
        return  true;
    }
    if(p[0] == NULL){ 
        printf("空文字列\t");
        return  true;
    } 
    printf("有効文字列\t");
    return  false ;
}
int     main(void) {
    printf("%d\n",isEmptyString(NULL)); //NULLポインタ  
    printf("%d\n",isEmptyString(""));   //空文字列
    printf("%d\n",isEmptyString("有効文字列"));
}

上記のコードはNULLポインタと終端文字¥0の区別がついていない
初級者の間違いです。
ポインタpを終端文字\0と比較したり
一文字のp[0] と NULLポインタを比較しています。


■非推奨例4:NULLポインタ判定が遅い

#include <stdbool.h>
#include <stdio.h>
bool    isEmptyString(const char  *p){
    if(p[0] == '\0' && p != NULL){ 
        printf("空文字列\t");
        return  true;
    } 
    if(p == NULL){
        printf("NULLポインタ\t");
        return  true;
    }
    printf("有効文字列\t");
    return  false ;
}
int     main(void) {
    printf("%d\n",isEmptyString(NULL)); //NULLポインタ  
    printf("%d\n",isEmptyString(""));   //空文字列
    printf("%d\n",isEmptyString("有効文字列"));
}

上記のコードは
p != NULLの判定をする前に
p[0] を参照してしまった例で
これでは p がNULLの時NULL参照が発生してしまいます。
先に p != NULL の判定を行う必要があります。


参考:

C-FAQ5.13: “ヌル”とか”NULL”とか”ナル”という単語が無造作に使われるときは以下のどれかを意味する。

http://www.kouno.jp/home/c_faq/c5.html#13