【C言語】
大文字⇔小文字変換
isupperとtolower

大文字/小文字 変換 isupperとtolower

■isupper()を使った大文字小文字変換(推奨)

#include <ctype.h>
#include <stdio.h>
void    大文字小文字変換(char *line){
    for(char *cp = line;*cp != '\0';cp++){
        if(!isalpha(*cp)) {
            continue ;
        }
        if(isupper(*cp)) {   
            *cp = tolower(*cp);
            continue ;
        }
        if(islower(*cp)) {
            *cp = toupper(*cp);
            continue ;
        }    
    }
}
int main(void){
    char    buf[BUFSIZ] ;
    printf("大文字と小文字の英数字を入れてね");
    fgets(buf,BUFSIZ,stdin);
    printf("↑:%s",buf);
    大文字小文字変換(buf);
    printf("↓:%s",buf);    
}

標準ヘッダctype.hで定義されている
標準関数を使うと
コードが読みやすくなります。


■文字定数を使った大文字小文字変換

#include <stdio.h>
void    大文字小文字変換(char *line){
    for(char *cp = line;*cp != '\0';cp++){
        if(('A' <= *cp) && (*cp <= 'Z')) {   
            *cp = *cp - 'A'+'a';
            continue ;
        }
        if(('a' <= *cp) && (*cp <= 'z')) {
            *cp = *cp - 'a' + 'A';
            continue ;
        }   
    }
}
int main(void){
    char    buf[BUFSIZ] ;
    printf("大文字と小文字の英数字を入れてね");
    fgets(buf,BUFSIZ,stdin);
    printf("↑:%s",buf);
    大文字小文字変換(buf);
    printf("↓:%s",buf);    
}

■16進数字を使った大文字小文字変換(非推奨)

#include <stdio.h>
void    大文字小文字変換(char *line){
    for(char *cp = line;*cp != '\0';cp++){
        if((0x41 <= *cp) && (*cp <= 0x5A)) {   
            *cp = *cp - 0x41 + 0x61;
            continue;
        }
        if((0x61 <= *cp) && (*cp <= 0x7a)) {
            *cp = *cp - 0x61 + 0x41;
            continue;
        }   
    }
}
int main(void){
    char    buf[BUFSIZ] ;
    printf("大文字と小文字の英数字を入れてね");
    fgets(buf,BUFSIZ,stdin);
    printf("↑:%s",buf);
    大文字小文字変換(buf);
    printf("↓:%s",buf);    
}

16進定数の意味をアスキーコード表で調べる必要があり、
ちょっと見ただけでは何をしてるのか
分からなくなります。(非推奨)


if(isupper() == true)は間違い

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main(void){
    char    buf[] = "abcd123EFG456hijk789";            
    printf("変換前 %s\n",buf);    
    for(char *cp = buf;*cp != '\0';cp++){
        if(isupper(*cp) == true){
            *cp = tolower(*cp);
            continue;
        } 
        if(islower(*cp) == true){
            *cp = toupper(*cp);
            continue;
        }
    }    
    printf("変換後 %s\n",buf);
}

警告:isupper()の戻り値は true/falseではありません。

isupperは
ゼロか非ゼロを返しますが、
非ゼロが1とは限りません。

なのでこのプログラムは期待した
大文字小文字変換を行いません。


falseと比較すると動く(非推奨)

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main(void){
    char    buf[] = "abcd123EFG456hijk789";            
    printf("変換前 %s\n",buf);    
    for(char *cp = buf;*cp != '\0';cp++){
        if(isupper(*cp) != false){
            *cp = tolower(*cp);
            continue;
        } 
        if(islower(*cp) != false){
            *cp = toupper(*cp);
            continue;
        }
    }    
    printf("変換後 %s\n",buf);
}

このプログラムは期待した
大文字小文字変換を行います。

しかし、
if(isupper(*cp) != false)を
日本語で読み上げると
「もし*cpが大文字であるならばが偽でなければ」のようになり読みにくいです。


明示的な検査をしない(推奨)

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main(void){
    char    buf[] = "abcd123EFG456hijk789";            
    printf("変換前 %s\n",buf);    
    for(char *cp = buf;*cp != '\0';cp++){
        if(isupper(*cp)){
            *cp = tolower(*cp);
            continue;
        } 
        if(islower(*cp)){
            *cp = toupper(*cp);
            continue;
        }
    }    
    printf("変換後 %s\n",buf);
}

このプログラムは期待した
大文字小文字変換を行います。

if(isupper(*cp) )を
日本語で読み上げると
「もし*cpが大文字ならば」のようになり
読みやすいです。


参考:

EXP20-C. 成功、真偽、等価を判定するには明示的な検査を行う

C-FAQ9.2一般にTRUEやFALSEを相手に明示的にテストするこ とは望ましくない。

■アンケート

1
もしxが大文字ならば?をどう書きますか?