isalpha()関数について

このQ&Aのポイント
  • isalpha()関数を使用して英字かどうか判別する方法について困っています。
  • 現在、char型配列に入力された文字列の2文字目が英字かどうかを判別して分岐させる処理を書いています。
  • しかし、isalpha()関数を使用しても思い通りの結果が得られず困っています。ソースコードとともに詳しく教えていただけると助かります。
回答を見る
  • ベストアンサー

isalpha()関数について

isalpha()関数について ◆開発環境 OS:Linux(Ubuntu9.10) コンパイラ:gcc4.4 IDE:eclipse 言語:C 《質問内容》 現在、char型配列A[8](最大8桁の文字列が格納されるため)に英字から始まる文字列(英字・数字)を入力し、 2文字目の文字を英字かどうか判別し、if文で分岐させようとしているのですが、 この2文字目の文字をisalpha()にかけても、英字と判別せず、思い通りの処理ができない状態で 困っています。 現状、以下のソースですと、"D0"ならelse ifに入りますが、"SM0"と入れるとifに入らずに、else ifに入ってしまいます。(2文字目は英字なのに…) 以下に、参考ソースを添付します。 どなたか、お分かりの方いらっしゃいましたら、ご教授お願いします。 できれば、isalphaの使い方等も詳しく教えていただけたら幸いです。(webで調べるとisalpha(int c)と書いてあり、文字の判別にint?とかなり疑問です。一応、ソース上ではchar型にキャストしてますが。) 《ソース》 char A[9]="";      //最大8桁の文字列(英字・数字)が入る char B[3]="";        //A,B入れ替え用バッファ char C[7]=""; //最大6桁の文字列(数字)が入る char code[2]="";      //判別用バッファ int C_val; //Cの10進値格納変数(後で使う) fscanf(stdin,"%s",&A); strncpy(code,,A+1,1);                  //code[2]に"0"をコピー if( (unsigned char)isalpha(code) != 0){          //codeが英字なら先頭2文字は英字 strncpy(B,A,2);             strncpy(C,A+2,strlen(A)-2); C_val=atoi(C); //Cの10進化 strcpy(A,"");    //Aの初期化 strcpy(A,B); strcpy(B,""); //Bの初期化 } else if( (unsigned char)isalpha(code) == 0){    //codeが英字でないなら先頭1文字が英字 strncpy(B,A,1); strncpy(C,A+1,strlen(A)-1); C_val=atoi(C);          //Cの10進化 strcpy(A,""); //Aの初期化 strcpy(A,B); strcpy(B,""); //Bの初期化 }

noname#107905
noname#107905

質問者が選んだベストアンサー

  • ベストアンサー
  • Lchan0211
  • ベストアンサー率64% (239/371)
回答No.4

No.1さんの回答通り、isalphaの引数の型はintですが、 そこには文字(char)を指定します。 文字列へのポインタ(char *)ではありません。 なぜ文字を指定するのにint型で定義されているのかは、 http://okwave.jp/qa/q4151525.htmlhttp://okwave.jp/qa/q5326377.html を参考にしてください。 なお、提示されたソースは、かなり無駄があるように見えます。 BもCもcodeも不要で、 -------------------------- char A[9]; int C_val; fscanf(stdin,"%s",&A); if(isalpha(A[1]) == 0) { C_val=atoi(A+1); A[1]='\0'; } else { C_val=atoi(A+2); A[2]='\0'; } -------------------------- で十分なように思えます。

noname#107905
質問者

お礼

早速の回答ありがとうございました。 コメントいただいたソースをもとに、実仕様にアレンジしたところ、無事解決することができました。 また、無駄な処理もコメントにより、省くことができ、大変助かりました。

その他の回答 (3)

回答No.3

別件 >strncpy(code,,A+1,1);     //code[2]に"0"をコピー ソース通りなら、コンパイルできません。 コメント通りならソースの記述が間違ってます。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

isalphaは文字コードの数値で判定します。 文字列ではありません。 f( (unsigned char)isalpha(code) != 0) では、「配列codeのアドレス」を「文字コード」と思って判定しようとしますので、真になることはめったにないでしょう。 isalpha(code[0]) とするのが正解です。さらに言えば、コピーする必要すらなく isalpha(A[1]) で十分です。 あとは ・(unsigned char)とキャストする意味がありません。 ・ if( (unsigned char)isalpha(code) != 0){ でelseへ分岐したのなら else if( (unsigned char)isalpha(code) == 0) { のifの条件は必ず真ですから else { で十分です。

回答No.1

# warningでていないのかな? isalphaの引数はintです。 http://www.linux.or.jp/JM/html/LDP_man-pages/man3/isalpha.3.html >isalpha(code) では char* から int にキャストされ解釈されるのではないでしょうか? よって isalpha(code[0]) と指定すべきでしょう。 もっとも、codeという変数を使わずとも isalpha(A[1]) でOKでしょうけど。

関連するQ&A

  • 構造体が戻り値の関数についてわかりません

    問題文:文字列を保存する構造体word_pairを下記の様に定義する。 typedef struct word_pair{ char longer_word[10]; char shorter_word[10]; char combined_word[20]; int longer_word_length; int shorter_word_length; }word_pair_t; この構造体を新たに作成し、データをセットして返す関数 word_pair_t create_word_pair(char *a, char *b); を作成せよ。create_word_pairは以下の仕様を満たす。 create_word_pairは2つの文字列a,bを比較し、長い文字列をlonger_wordに、短い文字列をshorter_wordに代入する。また、これらの長さが同じ場合には辞書的に後ろのものをlonger_wordに、前のものをshorter_wordに代入する。もし、a,bがまったく同じ文字列であれば、エラーメッセージを出力した上で、longer_wordに入力された文字列をshorter_wordに空の文字列を代入する。またcombined_wordにはlonger_word とshorter_wordをスペース区切りで結合したものを代入する。 標準入力から文字列を2つ読み取り、create_word_pairを用いて、新たにそれらのデータが代入された構造体を作成した後に、これらのメンバ変数を全て、標準出力に表示するプログラムを作成せよ。 という問題で、とりあえず自分で細かい条件は無視して文字列を標準入力してから構造体のメンバに文字を格納するところまでやろうとしたのですが、strcpyするのに型が違うとコンパイルエラーが出たのですが、型は一緒だと私は思っているため、なぜ違うのかわかりません。 また辞書的に後ろ前をif文でどのように表現すればいいのかと、文字列結合にstrcatを使うと思うのですが、結合の合間にスペースをいれる方法が分かりません。以下自分のコード。 #include<stdio.h> #include<string.h> #define max 50 typedef struct word_pair{ char longer_word[10]; char shorter_word[10]; char combined_word[20]; int longer_word_length; int shorter_word_length; }word_pair_t; word_pair_t create_word_pair(char *a, char *b); int main() { char a[max],b[max]; word_pair_t *str; printf("文字列を2つ入力してください。\n"); printf("1つ目:"); scanf("%s\n",a); printf("2つ目:"); scanf("%s\n",b); create_word_pair(a,b); printf("長い方の文字列%s\n",str->longer_word); printf("短い方の文字列%s\n",str->shorter_word); printf("連結した文字列%s\n",str->combined_word); printf("長い方の文字列の長さ%d\n",str->longer_word_length); printf("短い方の文字列の長さ%d\n",str->shorter_word_length); return 0; } word_pair_t create_word_pair(char *a, char *b) { int d, e; char c[max]; word_pair_t *str; d = strlen(a); e = strlen(b); if(d > e){ strcpy(str->longer_word, a); strcpy(str->shorter_word, b); c = strcat(a,b); strcpy(str->combine_word, c); strcpy(str->longer_word_length, d); strcpy(str->shorter_word_length, e); } if(d < e) { strcpy(str.longer_word, b); strcpy(str.shorter_word, a); c = strcat(a,b); strcpy(str.combine_word, c); strcpy(str.longer_word_length, e); strcpy(str.shorter_word_length, d); } }

  • 文字を置き換える関数で分からないことがあります。

    文字列strの中にある、文字列bagと共通の文字を空白に置き換える関数とその動作を確認するための、空白に置き換えた文字列strを表示するプログラムですが、戻り値が正しくないそうです。 ヒントでもいいのでどう直せばいいのかどなたかお教え下さい。 #include <stdio.h> char str_space(char str[], char bag[]){ int a, b, c, d; for(a = 0; a <= 99; a++){ if(str[a] == '\0'){ c = a; break; } } for(a = 0; a <= 99; b++){ if(bag[a] == '\0'){ d = a; break; } } for(a = 0; a <= c; a++){ for(b = 0; b <= d; b++){ if(str[a] == bag[b]){ str[a] = ' '; } } } return str[]; } int main(void){ char str[100], bag[100]; scanf("%s", str); scanf("%s", bag); printf("%s", str_space(str, bag)); return 0; }

  • 関数の戻り値なんですが...

    VC++を使用し以下のような関数additionで文字列を返したいのですが アドレスしか返しません。配列はその先頭のポインタだということは しっているのですが.... additionは、二つの文字列(32や47などの数字のやつ)を引数とし、そ れを整数型に変換し、その加算を行い、その結果を文字列型に変換し 、その文字列をかえす関数です。 関数の定義などが間違っているのですか?? #include<iostream.h> #include<string.h> #include<string> char *addition(char *,char *); void main(){ using namespace std; char a[] = "1000"; char b[] = "456"; cout << addition(a,b) << '\n'; } char *addition(char *a,char *b){ int c = 0; c = atoi(a)+atoi(b); char p[20]; _itoa(c,p,10); cout << p <<'\n'; return (*p); }

  • エクセル関数 22通りあるものを判別

    こんにちわ。エクセル関数を使用してうまく判別する方法があるか教えてください。 1000件くらいあるデータから22通りあるものを自動で判別できないか? A列は2種類、B列は11種類ある文字列からC列で固定値を出したい。   A列  B列  C列 1行 A   あ   ア 2行 B   い   イ 3行 A   う   ウ 4行 B   え   エ 5行 A   お   オ 6行 B   か   カ ・・・・・・・・22行まで 自分で調べて =IF(AND(A1="A",B1="あ"),"ア", IF(AND(A1="B",B1="い"),"イ", IF(AND(A1="A",B1="う"),"ウ", IF(AND(A1="B",B1="え"),"エ", IF(AND(A1="A",B1="お"),"オ", IF(AND(A1="B",B1="か"),"カ", IF(AND(A1="A",B1="き"),"キ", "チェック!!"))))))) などと途中までいい感じでできていたのですが、IF(AND(A1="B",B1="く"),"ク"を入力したらうまくいかなくなりました。 どなたかいい方法をお教えください。

  • Consoleアプリケーションの、「cin >>」について

    //一文字入力のつもりで、作ったのですが、 //「abcd」と打って、Enterすると、 //「a」→「A」 //「b」→「B」 //「c」→「C」 //「d」→「D」 //と、連続変換するのですが、 // cin >> -- ; というのは、 //どういうことでしょうか? // すみません、初心者です。 // よろしくお願いします。 #include <iostream> using namespace std; int main() { char inputchar; char outputchar; char Str1[12],Str2[12]; int chrcode; while(chrcode-120) { cin >> inputchar; chrcode = ( inputchar + inputchar ) / 2; if(chrcode >=65 && chrcode<=90) { outputchar=inputchar+'a'-'A'; strcpy(Str1,"大文字"); strcpy(Str2,"小文字"); } if(chrcode >=97 && chrcode<=122) { outputchar=inputchar-'a'+'A'; strcpy(Str1,"小文字"); strcpy(Str2,"大文字"); } cout << Str1 << "[" << inputchar << "]→" << Str2 << "[" << outputchar << "]" <<endl; } return 0; }

  • ライブラリ関数

    文字列をコピーする(strcpy) 文字列の長さを調べる(strlen) 配列の長さを調べる(sizeof) #include <stdio.h> #include <string.h> int main(void) { char s1[128] = "ABCD"; char s2[128] = "EFGH"; char s3[128] = "IJKL"; strcpy(s2, s1); strcpy(s3, s2); puts("s1をs2にs2をs3にコピーしました。"); printf("s1 = %s\n", s1); printf("s2 = %s\n", s2); printf("s3 = %s\n", s3); printf("文字列%sの長さは%uです。\n",s3,(unsigned)strlen(s3)); printf("文字列%sの長さは%uです。\n",s3,strlen(s3)); return (0); } char *strcpy(char *d, const char *s) { while (*d++ = *s++) printf("pointer=%s \n",d); } /* 文字列sをdにコピーする[配列版] */ char *strcpy(char d2[], const char s2[]) { unsigned i=0; while (d2[i] = s2[i]){ i++; printf("hairetsu=%s\n",&d2[i]); } } /*--- 文字列strの長さを返す[ポインタ版] ---*/ size_t strlen(const char *s) { size_t len = 0; while (*s++) len++; return (len); } /*--- 文字列strの長さを返す[配列版] ---*/ unsigned strlen(const char str[]) { unsigned len = 0; while (str[len]) len++; return (len); } c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(48) : error C2084: 関数 'char *strcpy(char *,const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の前の定義を確認してください c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(68) : error C2084: 関数 'size_t strlen(const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(80) : 'strlen' の前の定義を確認してください 上記の問題が解決できません。助けてください><

  • 文字列→数値変換関数

    ・数字文字列を数値化する関数AtoS()を制作する。 書式:short AtoS(char *pStr, int *pRetCode); 引数:char *pStr; 文字列の先頭アドレス    int *pRetCode; 動作の正否を返す 戻り値:pStrを数値化した値 処理: pStrで与えられた文字列をshort型に変換する。 呼び出し側の書式は以下の通りです。 void main(void) {  short val; int code; val = AtoS("1234", & code); printf("%d\n",val); val = AtoS("-789", & code); printf("%d\n", val); } です。専門学校の明日の朝までの課題なのでどうか、どなたか助けて下さい。 

  • 関数について

    char *str_char(const char *str, int c) { while (*str++) if (*str == c) return ((char *)str); return (NULL); } /*文字列strから文字cを検索し最初に存在する文字へのポインターを返す*/ 上記関数なのですが 5行目を return (str); にしてはなぜいけないのでしょうか。

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • 初歩的な関数なのですが、教えてください。

     A列 B列 C列 D列 E列 1               鶴    2 あ  鶴  あ 3 い  亀   4 う   5    鶴 6 う 7 え  鶴  え 8    亀 9 E1のセルに「鶴」(任意の文字)をいれます。 A列に文字が入っていて、かつ、B列の文字=E1の文字(鶴)ならA列の文字をC列に返す。 A列に文字が入っているが、B列の文字がE1の文字と異なる(亀)ならC列は空白。 A列に文字が入っているが、B列の文字が空白ならC列は空白。 A列が空白なら、B列に鶴、亀、その他の文字が入っていても空白。 A列、B列ともに空白なら、C列も空白 上記を可能にする関数がわかりません。 IF関数を使うのだと思うのですが。 エクセルの2003です。よろしくおねがいします。

専門家に質問してみよう