- ベストアンサー
Cの文字操作(置換)について
Cを始めたばっかりのものです。 いままでPerlとPHPでCGIを書いてますが、それをCに書き換えています。 今のところフォームをデコードして、nameを入れるとvalueを返す関数をつくって、さあこれから、という状況です。 基本的な質問ですが、Cには文字列の置換をしてくれる関数ってありますか? たとえば、標準のライブラリに入ってなくても、どっかからダウンロードできるとか。 なければstring.hに入っている関数を使って自分で作ろうかと思ってますが、作った後に、“xxxxをつかったら一発でできるじゃん”という発見がすごいショックで、今までもなんどもありましたので、おたずねします。 よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
> これでなぜ漢字コード非対応なのかがよくわかりません。 置き換えられる対象文字(substr1)が1バイト文字1文字ではなく、2文字以上もしくは2バイト文字だったら文字コードが重なる可能性が少なくて、strstrでも2バイト文字の1バイト部分を切ったりしないと考えて大丈夫ですか? この点については漢字コードの種類に依存します。例えばシフトJISの場合、2バイトのうちの1バイト目と2バイト目のコードの範囲は重なっています。このため、ある漢字1文字をsubstr1に指定した場合、2文字続く2バイト文字(全4バイト)の中央の2バイトが置換されてしまう可能性があります。また、一般には2バイト文字は1バイト文字と混在しているので、問題はさらに複雑になります。私はあまり詳しくないのですが、シフトJIS以外の漢字コードも同様の問題を抱えていると思います。
その他の回答 (4)
- gimmick
- ベストアンサー率49% (134/270)
#3の者です。StrReplace()の置換処理部分を変更させてください。こちらの方が少しわかりやすいので。 ------------------------------------------------ /*置換処理*/ while ((q = strstr(p, substr1)) != NULL) { /*置換しない部分のコピー*/ strncpy(r, p, q - p); r += (q - p); /*置換文字列のコピー*/ strcpy(r, substr2); r += len2; /*検索開始位置の更新*/ p = q + len1; } strcpy(r, p); /*最後の部分のコピー*/
補足
ありがとうございます。 大変参考になります! これでなぜ漢字コード非対応なのかがよくわかりません。 置き換えられる対象文字(substr1)が1バイト文字1文字ではなく、2文字以上もしくは2バイト文字だったら文字コードが重なる可能性が少なくて、strstrでも2バイト文字の1バイト部分を切ったりしないと考えて大丈夫ですか? もしよろしければご回答よろしくお願いします。
- gimmick
- ベストアンサー率49% (134/270)
C言語で文字列置換をするような標準関数はなかったと思います。ちょっと面倒だと思いつつも自作してみたので参考にしてください。ただ、いろいろと不完全だと思うので注意してください。(漢字コード非対応とか) なお、インデントには全角空白を使っています。 ------------------------------------------------- #include <stdio.h> #include <string.h> #include <stdlib.h> int StrCount(const char *str, const char *substr); void StrReplace(const char *input, const char *substr1, const char *substr2, char *output); int main(){ char *string = "acabcdeabced"; char *substr1 = "ab"; char *substr2 = "XYZ"; char *output; size_t outSize; size_t len, len1, len2; int count; /*出力領域の確保*/ len = strlen(string); len1 = strlen(substr1); len2 = strlen(substr2); count = StrCount(string, substr1); outSize = len + count * (len2 - len1) + 1; output = (char *)calloc(outSize, sizeof(char)); if (output == NULL) { return 1; } /*置換処理*/ StrReplace(string, substr1, substr2, output); /*確認*/ printf(string); printf("\n"); printf(output); printf("\n"); /*終了*/ free(output); return 0; } /*部分文字列の出現回数を調べる*/ int StrCount(const char *str, const char *substr){ const char *p = str; int cnt = 0; size_t len; len = strlen(substr); while ((p = strstr(p, substr)) != NULL) { cnt++; p += len; } return cnt; } /*文字列の置換処理*/ void StrReplace(const char *input, const char *substr1, const char *substr2, char *output){ size_t len1, len2; const char *p = input; const char *q = input; char *r = output; /*初期化*/ len1 = strlen(substr1); len2 = strlen(substr2); /*置換処理*/ while ((p = strstr(p, substr1)) != NULL) { /*置換しない部分のコピー*/ strncpy(r, q, p-q); r += (p-q); /*置換文字列のコピー*/ strcpy(r, substr2); p += len1; q = p; r += len2; } strcpy(r, q); /*最後の部分のコピー*/ return; }
- muyoshid
- ベストアンサー率72% (230/318)
こんにちわ。 strstr 関数で、置換する文字列を検索して、strcpy 関数で 該当箇所にコピーすればOk だと思います。
補足
早速ありがとうございます。 やっぱり、一発で置換してくれる関数はないということですね。 strstrとstrcpyを使った場合、'\n'を"<br>"で置き換えたい場合は元の文字列と、処理後の文字列の長さが変わってしまうので、別の文字列にコピーしていったほうがいいいでしょうか?
- kmor
- ベストアンサー率27% (225/825)
すみません、今手元に資料がないので詳細はわかりません。 ポインタとstrcpy関数を使えば出来ます。 strcpyのパラメタの詳細を忘れてしまったので。 多分 char * strcpy(char * コピー先, char * コピー元) だったような気がします。
お礼
ありがとうございました。 いろいろ試してみます。 ほんとに参考になりました。 またお願いします。