■この記事の概要
この記事では、C言語で大文字・小文字の判定と変換方法を解説します。
標準ライブラリctype.h
のisupper()
やtolower()
などを使った効率的な実装方法や、非推奨の16進数変換の例も紹介。
エラーを避けるためのベストプラクティスを解説し、初心者にもわかりやすいコード例を通して、より安全で読みやすいC言語の書き方を学べます。
■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を相手に明示的にテストするこ とは望ましくない。