• ベストアンサー

1バイト文字と2バイト文字の区別の仕方

C++についての質問です。 簡単な質問で大変申し訳ございません。 '\'や'&'などSQLインジェクションに 関係する文字コードについて 空白に変換する処理をいれていたところ、 カタカナの「ソ」(%83%5c)など も変換されてしまい、 文字化けしてしまうという現象が起きています。 '\'は、'%5c'のため、カタカナの「ソ」は、 それと同じ'5c'のコードが 2バイト目入ってしまっているからだと いう原因までは、 把握しているのですが、 対処の仕方がわかりません。 簡単な質問で申し訳ございませんが ご教示願います。

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

  • ベストアンサー
  • Willyt
  • ベストアンサー率25% (2858/11131)
回答No.3

 文字コードを空白に変換するというのは危ないのではないでしょうか。文字化けが起きたということはそのコードの中の1ビットが化けたか、データが混入したか、脱落したかが考えられます。それのどれであるかということは前後のデータの並び方から推定する他はないのですが、これはかなり大変な作業になります。  ですからデータを頭から正しいものと決め込んで特殊コードを空白コードに変換する作業を機械的に行なうということは大変危険な作業であるということになり、文字化けが起きたときには作業を中止し、その原因を推定するルーチンに飛込むようにしなければなりませんね。  今回の場合はデータがずれてしまっているようですから、これは1ビット脱落したか混入したかのどちからですから、場合に分けたルーチンを用意するのも一つの手段かと思います。  いずれにせよ、データをいじるのは大変危険な作業なので、薄氷を踏むような用心が必要ということになりますね。  私が現場でやっていた頃はまだすべて2バイトコードでしたが、それでも血の出るような思いを何度もしたことがあります。御苦労はお察ししますよ。

参考URL:
http://home.a03.itscom.net/tsuzu/programing/tips07.htm
googoocgi
質問者

お礼

お忙しい中、返信くださいまして どうもありがとうございます。 実際に行っている処理としては、 「サシスセソ」という文字列に 「\」、「'」、「"」、「&」などの不正コードが 入力されてしまった場合は、 // 文字列除去処理 int find_len = strlen(find); char *start = str; char *hit; while ( ( hit = strstr(start, find) ) ){ strcpy( hit, hit+find_len ); } 不正文字を詰めるようにしています。 ただし、上記処理をあらゆる文字に対し行った場合は、 文字が落ちてしまうため、 2バイト文字については、文字列除去処理を行いたくありません。 そこで、以下の処理を書いています。 #define 2bytechar(c) ((((unsigned char)(c))!=0x7F)&&(((unsigned char)(c))>=0x40)&&(((unsigned char)(c))<=0xFC)) for ( i=0; str[i] != '\0' i++ ) { if ( 2bytechar( str[i] ) ){ //進める  i++; } else { //文字列除去処理呼び出し } しかし、 上記の場合は、 「サシスセソ」が文字化けすることはなくなりましたが、 「\サシスセソ」とした場合は、 「\」が削除されなくなってしまいました。 どのように対応すればよいでしょうか? 拙い文章な上に、 細かい部分まで質問してしまいまして 申し訳ございませんが、 宜しくお願い申し上げます

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

> #define 2bytechar(c) ((((unsigned char)(c))!=0x7F)&&(((unsigned char)(c))>=0x40)&&(((unsigned char)(c))<=0xFC)) このマクロのロジック間違っていませんか? 後の処理とあわせて考えると多分ShiftJISの上位バイトとみなせる ときに下位バイトを処理対象からはずすということをしたいのでしょうけど、 上記のマクロでは 1. 0x7f ではなく 2. 0x40 <= x <= 0xFC の範囲にあるキャラクタのときに真になりますから、'\'をこのマクロに 食わせると真になってしまいます。 ShiftJISの上位バイトの分布をもう一度見直してみては? もしWindows上のC処理系を使っているのなら、判定を行ってくれる関数が多分ありますし、Windows APIにも存在しています。

  • Willyt
  • ベストアンサー率25% (2858/11131)
回答No.4

>「\サシスセソ」とした場合は、「\」が削除されなくなってしまいました。  ご呈示のロジックなら独り¥だけが残る筈がありませんよね。これはC++のスペックで \ に何か特殊の意味を与えていて、組み込み関数がこれを無視するからではないかと推測します。  ですからこれの対策は1バイトを切出したときに組み込み関数で2バイトコードと1バイトコードを弁別するのをやめて、ビットオペレーションを使い、自前で判断することでしか解決できないと思います。コード表をにらみながら効率的なルーチンを編み出してください。20年若ければご一緒に考えるところですが、古稀に近くなるともうダメです(^_^;)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

拡張文字集合の扱いは、今直面している0x5cの問題だけでなく、その他のこともすべて視野に入れた上で、どうすべきか決定する必要があると思います。 文字列中の文字をランダムアクセスする頻度が赤いのであればワイド文字列に直した方がよいでしょうし、文字列の順序付けを変更したくないのであれば、シフトJISのままにしておく必要があります。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 基本的にはshift-jisに起因する問題になります。 ですので、対応策としては ・文字コードをあらかじめshift-jis以外(通例EUC。最近だとUTF-8であることも多い)に変換する ・Shift-jisコードであるかどうかを1バイト目の値で判断する のいずれかになるかと思います。 とりあえずお勧めは1番目でしょうか? 結局のところ、こういう部分が「内部処理でsjis使うな」といわれている所以なので。

関連するQ&A

  • 1バイト文字から2バイト文字に変換

    C言語にて Char a = "-"; 上記のような直打ちのASCII(1バイト文字)をUCS-2(2バイト文字)に文字コードを利用して変換する方法がわかりません。 わかる方がいらっしゃいましたら助けて頂けるとありがたいです。

  • phpMyAdmin、インポートで全角カナ文字化け

    レンタルサーバでphpMyAdminもレンタルしています。 csvファイルをインポートしているのですが、 どうやらちょっとずつ文字化けしているようです。 やっと分かったのは 【1】 「ソ」が「ャ」になり、「ソ」以降のカタカナが文字化けしています。 (ソがない場合は、上記ソ以降の文字はきちんと表示されます) また、「予感」という字も「頼ェ」になっていました。 (テーブル数が少ない場合、上記の文字化けは起こりませんでした  また、phpMyAdmin上で入力すると、きちんと表示されます) 【2】 また、データに「─」や「圭」が入っていると、「CSV 入力のフィールド数が不正です」 というエラーが発生します。 【3】 こちらは、phpで作ったフリーワード検索ですが、 POST送信した際、「メ」→「ƒ」、「ー」→「[」と変換されます。 インポートするカタカナは、全角カタカナしか使っていません。 ───────────────────── MySQL: サーバのバージョン: 5.0.77-log プロトコルバージョン: 10 MySQL の文字セット: UTF-8 Unicode (utf8) Web サーバ Apache MySQL クライアントのバージョン: 5.0.45 PHP 拡張: mysqli phpMyAdmin:バージョン 3.2.4-rc1 ───────────────────── 文字コードはシフト-jisに統一しています。 (色々試しましたが、UTF・EUCでは、インポートした時点で主に「????」の文字化けが発生) 本当に行き詰ってしまい、テーブルデータなどを全て消して1から作り直したのですが…同じでした。 データ数が大変多いので、文字化けしているところを1つずつ直すというのはできません。 初歩的なミスなのかもしれませんが、思い当たらず質問をさせていただきました。 どなたかご存じの方がいらっしゃいましたら、ご教授お願い致します。

    • ベストアンサー
    • MySQL
  • 文字コードの迷宮に迷い込みました

    言語がPHP(SJIS)でDBがMySQL(Unicode)の環境で運用しているページがあるのですが、文字コードの変換で謎が謎を呼び始めたので質問します。 (1)フォームからの保存で「ソ」の文字を保存するとDB上で「ソ\」になります。 →コード変換ミス(5c=\)で理解しました。 (2)「ソ\」で保存されたデータをフォームに呼び出すと「ソ\」と表示される。 →UTF8で「5C=\」だから?? (3)上記を回避したくPHPでstripslashesを追加してみると、「ソ」の表示が「メ」になってしまっている。 なぜこうなるのか??回避できないのか?? という点で不思議と謎につつまれているのですが、コメントお願いします。

    • 締切済み
    • PHP
  • 2バイト文字が文字化けする!

    次の条件でデータが送られてくるのですが、エディタで開くと2バイトのところだけ文字化けします。 きちんと2バイト文字を表示させたいのですが、なにか方法はありますでしょうか? 教えてくださいますよう、宜しくお願いします。 【使用コード】 ・1バイト文字:JIS X0201(1976)に準拠するJIS8コードセット ・2バイト文字:新JIS(JISC6226-1983)に準拠するコード 使用OS:Windows2000Pro 使用エディタ:EmEditor v3

  • 置換えについて

    $com =~ s/\\/\/g; ↑のようにすると、能、ソ、申、等の2バイト目が「5C」コードになっている文字も変換されてしまいます。これを防ぐよい方法はないでしょうか? Perlはあまりよくわからないため、意味不明な説明でしたら申し訳ございません。

    • ベストアンサー
    • Perl
  • VS2005C#でメールを受信すると文字化け

    VS2005C#でメールを受信するときに文字コードをiso-2022-jpで変換し、 大抵のメールはこれでOKなのですが、 たまに文字化けしてしまうメールがあります。 しかし普通のメーラーで見ると文字化けせずに見えます。 ヘッダにもiso-2022-jpと書かれています。 C#で受信したときに文字化けしてしまう理由は何かあるのでしょうか? バイトが欠損しているからでしょうか? (そうなら普通のメーラーでも文字化けすると思うのですが)

  • 2バイト文字をASCIIコードに変換

    SQL Server初心者です。 SQL Serverで2バイト文字をASCIIコードの値で返したいのですが、関数ASCII()を使用すると、1バイト目のASCIIコードの値しか返してくれません。 2バイト目の文字も返す方法をご教授ください。 言葉足らずでわかりにくいかと思いますが、よろしくお願い致します。

  • PHPでの文字化け修正ツールの作り方を教えて下さい

     なんか「ググれやボケカス!」とか怒られそうな丸投げ的な質問で申し訳ありません(^_^;  ネット上にはすでに文字化けした文章を、デコードと言いますか、本来の文字コードに変換して読めるようにしてくれるサイトがあったりしますが、あれをPHP使って自分で作れないかなと。  ただ、自分でいろいろ調べてみたものの、いまいち仕組みが全然分からないんですよね。  「urldecode」でできるかなと思いましたが、これってURLエンコードされたものを戻すやつですからもちろんダメ。  「mb_convert_encoding」で文字化け後のコードから文字化け前のコードに戻せるかと思ってたら、文字化けした文字をそのままコード変換するだけなのでまったくの無意味。  あれってどうやって文字化け修正してるんでしょうか?  1から10まで教えて下さいとは言いませんので、せめて「こういうキーワードで検索しろ」というものがあれば教えて下さい。

    • 締切済み
    • PHP
  • UTF8コードで1バイトの文字が2バイトで表現されているのですが・・・・?

    UTF8コードで1バイトの文字が2バイトで表現されているのですが・・・・? とタイトルの通りデータに    UTF-8のデータを扱っていて  16進表記で『0xC341』と  データが入ってきました。 0xC3…11000011  0x41…01000001 UTF-8の仕様で2バイト目の文字は先頭ビットが 10 から始まる仕様となっていると思いますが  2バイト目の先頭ビットが 0 の場合はUTF-8コードが  壊れていると判定してもいいんですか?    それとも、2バイトの先頭ビットが0の場合  次のバイトを1バイト文字とし変換してあげて  0x41 → A として変換するなどといった  特殊な仕様が隠れていたりするのでしょうか?    今のところ壊れていると判断しているのですが、  UTF-8ではないコードだったりする可能性もあるかな?  っと思い質問いたしました。  少し不安だったので、しっていましたら、教えてください。                          以上   検索ワード UTF-8 2バイト目 1バイト文字

  • 文字化け

    CGIの中に文字をして、 サーバーにアップして、アクセスすると、 ある一部のカタカナと漢字が文字化けを起す事があります。 例えば【ソ】【表】 文字化けをした場合、スクリプトを再度開きその部分の後ろに【\】をつければ解消する事は解っているのですが、 いちいちサーバーにアップして見なければ、 文字化けがおきているかどうか解らないので、 文字化けをおこす文字リストなどがあれば、 アップする前に対処できるので、 そう言ったリストはありませんでしょうか? 探して見てるのですが、なかなか見つかりません。

    • ベストアンサー
    • CGI