掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28088

半角全角の見分け方。
投稿者---ジョー(2006/09/11 16:19:48)


Cで半角全角の見分け方はありますか?
ネットで調べてみましたが、いまいち分かりません。
方法をご存知のかた教えてくださいませ。

何卒、よろしくお願い致します


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:半角全角の見分け方。 28089 たかぎ 2006/09/11 16:21:21


No.28089

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/11 16:21:21)
http://takagi.in/


>Cで半角全角の見分け方はありますか?

一般的な方法はありません。
半角・全角の定義と、使用している文字コードを明確にしてください。



この投稿にコメントする

削除パスワード

No.28090

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 16:28:21)


>半角・全角の定義と、使用している文字コードを明確にしてください。

すいません。
説明不足でした。

半角・全角の定義は
半角は1バイトで収まる文字、全角は2バイトで収まる文字です。
また文字コードはSJISです。





この投稿にコメントする

削除パスワード

No.28093

Re:半角全角の見分け方。
投稿者---dead man walking(2006/09/11 17:40:06)


>半角・全角の定義は
>半角は1バイトで収まる文字、全角は2バイトで収まる文字です。
>また文字コードはSJISです。

それが分かっているなら、あとは一バイトづつ読み込んで、半角か全角かを判断するだけです。
お約束の文字コード表を貼りますので、参考にしてください。

http://ash.jp/code/codetbl2.htm
http://ash.jp/code/code.htm #中ほどにSJISの範囲があります。

まぁ半角全角は、日本語を扱うシステムにとって最大のガンですから、
完璧に判断できるものを作るのは容易じゃないです。
自分も何度投げ出したくなったものか…

#半角カナのばっきゃろー


この投稿にコメントする

削除パスワード

No.28095

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 18:08:02)


みなさんありがとうございます。

あともう一点、
文字数を数えるプログラムを作成したいのですが、

例えば
↓これは5文字として扱います。
あいうえお
↓これは6文字として扱います。
あああABC

要は全角だろうが半角だろうが1文字としてカウントしたいわけです。

strlenではバイト数になってしまうし・・・。
標準関数で上記が実現可能な関数があれば教えてくださいませ


この投稿にコメントする

削除パスワード

No.28096

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/11 18:23:51)
http://takagi.in/


判別方法はすでに回答が出ている通りです。

>要は全角だろうが半角だろうが1文字としてカウントしたいわけです。
>
>strlenではバイト数になってしまうし・・・。
>標準関数で上記が実現可能な関数があれば教えてくださいませ

「標準関数で」とのことであれば、いったんmbstowcsまたはmbsrtowcs
でワイド文字列に変換してから、wcslenで文字数を調べることになります。
ただし、期待通りになるかどうかは処理系とロケールに依存します。





この投稿にコメントする

削除パスワード

No.28098

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 20:44:37)


ありがとうございます。
mbstowcs関数は例えば

↓下記のような文字列の場合

あああAAAいいい

↓下記のように変換してくれるのでしょうか?
あああAAAいいい

もし全角と半角が入り混じった文字列をmbstowcsにかけようとすると半角文字だけを全角にしてくれるのでしょうか?

実際試してみればいいのですが、ただいま、実行できない環境のPCですのでご存知でしたら教えてくださいませ。


この投稿にコメントする

削除パスワード

No.28101

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/11 21:41:34)
http://takagi.in/


>もし全角と半角が入り混じった文字列をmbstowcsにかけようとすると半角文字だけを全角にしてくれるのでしょうか?

半角を全角にするのではなく、文字列中の多バイト文字をすべてワイド文字に変換してくれます。
ワイド文字列に変換できれば、(期待通りに動いてくれる処理系&ロケールであれば)配列の1要素が1文字に相当します。


この投稿にコメントする

削除パスワード

No.28102

Re:半角全角の見分け方。
投稿者---yoh2(2006/09/11 22:04:43)


>↓下記のような文字列の場合
>
>あああAAAいいい
>
>↓下記のように変換してくれるのでしょうか?
>あああAAAいいい

No.
んー。マルチバイト文字とワイド文字が何者なのか誤解してると、mbstowcs()の
マニュアルを読んでも正しく理解できないですね。

マルチバイト文字:
1文字に使うバイト数が一定ではない文字からなる文字列。
Shift_JISやISO-2022-JPなど。

ワイド文字:
1文字に使うバイト数が一定の文字列。大抵1文字2バイト以上なのでこう呼ばれる。
つまり、ワイドなのは文字の見た目の幅ではなく、必要なデータ域ってこと。
ワイド文字の例はUTF-16、UTF-32など。
# UTF-16もサロゲートペアを考えるとマルチバイト文字なんだけど。閑話休題。

で、mbstowcs()は、いわゆる全角/半角の種別はそのままに、マルチバイト文字列から
ワイド文字列に変換する関数。
ワイド文字というのは、文字幅がワイドなのではなく、使うバイト数がワイドってこと。

mbstowcs()は、本来文字数を数える関数ではありませんが、ワイド文字の、文字数を
カウントしやすい性質を用いることで文字数を簡単に調べることができます。

ちなみに、文字数をカウントするだけなら、mbstowcs()→wcslen()としなくても、
mbstowcs()の第一引数をNULLにして戻り値を見るだけで事足ります。

しかし、たかぎさんも少し触れていますが、Cライブラリが、Shift_JIS文字列を
「マルチバイト文字列」として扱えるかどうかはライブラリの実装とロケール(*)の設定に
依存します。
OSによってはロケールの設定を何にしたところで、Shift_JISをマルチバイトとして
扱うことができない場合もあります。

Shift_JIS文字列を先頭から舐めて、それぞれが1バイト文字か2バイト文字の先頭バイトかを
調べるのは簡単ですので、標準関数にこだわるより、自作した方が手っ取り早いし
移植性も確保できてハッピーになれると思います。

(*)「ロケール」というのもややこしいもので、説明し出すと長くなるため、分からなかったら
「setlocale」あたりをキーワードに検索してみて下さい。


この投稿にコメントする

削除パスワード

No.28103

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 22:13:08)


>Shift_JIS文字列を先頭から舐めて、それぞれが1バイト文字か2バイト文字の先頭バイトかを
>調べるのは簡単ですので、標準関数にこだわるより、自作した方が手っ取り早いし
>移植性も確保できてハッピーになれると思います。

それは1バイトづつ取り出して文字コードで調べるということでしょうか?
文字コードでの比較等は経験がないので、そこがいまいち理解できないです・・・。
経験不足で申し訳ございません。この比較方法をご伝授いただけないでしょうか。


この投稿にコメントする

削除パスワード

No.28097

Re:半角全角の見分け方。
投稿者---shu(2006/09/11 18:38:46)


>strlenではバイト数になってしまうし・・・。
>標準関数で上記が実現可能な関数があれば教えてくださいませ

strlenを自作してみなさい。
あとは、ちょっと手を加えてやれば思っているものができる。
strlenを自作しないで、
ちょっとの手も加えてやらなければ、なにもできない。


この投稿にコメントする

削除パスワード

No.28099

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 20:47:21)


strlenを自作ですか?

いまいちイメージが浮かびません。
ヒントをいただけないでしょうか?


この投稿にコメントする

削除パスワード

No.28100

Re:半角全角の見分け方。
投稿者---shu(2006/09/11 21:27:22)


>いまいちイメージが浮かびません。
>ヒントをいただけないでしょうか?

文字列を表示するプログラムを作る。
文字列を一文字ずつ表示するプログラムを作る。
No.28097へ


この投稿にコメントする

削除パスワード

No.28104

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/11 22:32:10)


下記のような感じですか?

int main()
{
  /* 変数宣言 */
  char test[10];
  int i;

  for(i=0;i<10;i++)          
    {
      if(test[i]=='\0')
/**********************/
おそらくここで1バイト(test[i])が半角か全角か比較する?
/**********************/    
   break;
    }
}



この投稿にコメントする

削除パスワード

No.28105

Re:半角全角の見分け方。
投稿者---Blue(2006/09/11 22:58:49)


全角半角の判定ができているならば、

int my_strlen( const char* text )
{
    int length = 0;

    while ( *text != '\0' )
    {
        if ( /* *test が半角文字である場合 */ )
        {
            length++;
            text++; /* 1バイト進める */
        }
        else
        {
            length++;
            text += 2; /* 2バイト進める */
        }
    }
    return length;
}

int main( void )
{
    char s[] = "abcあいう";
    int length = my_strlen( s );
    printf( "%sは%d文字\n", s, length );
    return 0;
}

のような関数になるかと思います。(わかりやすいように若干冗長なコードになっています。)


この投稿にコメントする

削除パスワード

No.28106

Re:半角全角の見分け方。
投稿者---nano(2006/09/11 23:33:49)


dead man walkingさんが紹介してくださったWebサイトによると、
文字コードが0x81〜0x9Fまたは0xE0〜0xEFならば
全角の1文字目と判断できそうです。

それをBlueさんが提示されたコードに組み込めば、
自作のstrlen関数ができあがります。


この投稿にコメントする

削除パスワード

No.28112

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/12 09:57:31)


比較方法なんですが、下記のような比較だと警告がでるのですが、比較方法はこういう感じで行うんでしょうか?

while(*output_char != '\0')
{
    if(0x81<= output_char >= 0x9F)    
    {
        output_char ++;
    }
}



この投稿にコメントする

削除パスワード

No.28113

Re:半角全角の見分け方。
投稿者---nano(2006/09/12 10:03:50)


警告ではなくて、コンパイルエラーですよね?
if文の書き方を今一度確認してみてください。


この投稿にコメントする

削除パスワード

No.28114

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/12 10:06:42)


>警告ではなくて、コンパイルエラーですよね?
>if文の書き方を今一度確認してみてください。

警告でした。
ちょうどif文の箇所で下記のような警告です・・・。

警告: ポインタと整数との比較を行なっています


この投稿にコメントする

削除パスワード

No.28115

Re:半角全角の見分け方。
投稿者---Blue(2006/09/12 10:06:58)


> if(0x81<= output_char >= 0x9F)
C言語ではこのような記述方法はありません。

サンプル)
int n = 10;
if ( n >= 0 && n <= 10 )
{
    puts( "n は 0〜10 の値。" );
}


それと、私の挙げたコードにコメントとして書きましたが、
対象となるのは *output_charです。
*をつけないと、ポインタの値を比較することになります。


この投稿にコメントする

削除パスワード

No.28116

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/12 10:28:08)
http://takagi.in/


>> if(0x81<= output_char >= 0x9F)
>C言語ではこのような記述方法はありません。

あるかないかで言えば、あることはあります。
つまり、

if((0x81<= output_char) >= 0x9F)

の意味になりますので、
0x81 <= output_char の評価結果(0または1)と0x9Fを比較することになります。
もちろん、書いた人はそんなことは期待していないのでしょうが。



この投稿にコメントする

削除パスワード

No.28118

Re:半角全角の見分け方。
投稿者---Blue(2006/09/12 10:35:01)


>あるかないかで言えば、あることはあります。
そうですね。

構文的には間違いではないが、おそらく意図している(やりたい)ことは違う

というようにいうべきでした。

ご指摘ありがとうございました。


この投稿にコメントする

削除パスワード

No.28121

Re:半角全角の見分け方。
投稿者---ジョー(2006/09/12 12:21:40)


if文を書き直し
下記のようにしたところ

if(output_char >= 0x81 && output_char <=0x9F)


下記の警告が出ます。
output_charは*charで宣言しています。

警告: ポインタと整数との比較を行なっています

どうしてこのような警告が出るのか分かりません。
なにが原因なのでしょうか?




この投稿にコメントする

削除パスワード

No.28122

Re:半角全角の見分け方。
投稿者---Blue(2006/09/12 12:27:00)


>どうしてこのような警告が出るのか分かりません。
>なにが原因なのでしょうか?

私のレスの
>それと、私の挙げたコードにコメントとして書きましたが、
>対象となるのは *output_charです。
>*をつけないと、ポインタの値を比較することになります。
をよんでいないのでしょうか?



この投稿にコメントする

削除パスワード

No.28123

Re:半角全角の見分け方。
投稿者---dead man walking(2006/09/12 12:32:22)


゚Д゚)…
中学生か何かですか?

いい加減皆さんあきれてきた所でしょう。
ジョーさんに捧げる言葉を列挙してみましょう。

ノ他力本願
ノ自己研鑽
ノ先生に聞け
ノ友達に聞け
ノすぐに人を頼るなこのバカチンが
ノググれ
ノググれ
ノググれ


この投稿にコメントする

削除パスワード

No.28120

Re:半角全角の見分け方。
投稿者---shu(2006/09/12 12:19:05)


strlenを自作しなさいという書込みに対して

> strlenを自作ですか?

strlenを自作しなさいという書込みが既にヒントだったのですが

> ヒントをいただけないでしょうか?

さらにおまけヒントとして書いた書込みに対して

> 下記のような感じですか?

と再質問

全角半角の判定ができているならば、というBlueさんの書込みに対してさらに

> 比較方法はこういう感じで行うんでしょうか?


全体を通して、質問があいまい。
返信内容に対して読みが浅い。

半角全角の見分け方。というタイトルは良い。


この投稿にコメントする

削除パスワード

No.28124

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/12 12:50:15)
http://takagi.in/


>全体を通して、質問があいまい。
>返信内容に対して読みが浅い。

早い話が、C言語より先に母国語を学びましょうということですね。
それとも外国人なのかな?



この投稿にコメントする

削除パスワード

No.28125

Re:半角全角の見分け方。
投稿者---shu(2006/09/12 13:00:48)


>早い話が、C言語より先に母国語を学びましょうということですね。

違う!



この投稿にコメントする

削除パスワード

No.28126

Re:半角全角の見分け方。
投稿者---たかぎ(2006/09/12 13:23:59)
http://takagi.in/


>>早い話が、C言語より先に母国語を学びましょうということですね。
>
>違う!

国語力以外に原因があるとすると、かなり深刻です。
願わくは、国語力の問題であって欲しいのですが...



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧