• ベストアンサー

Cの文字操作(置換)について

Cを始めたばっかりのものです。 いままでPerlとPHPでCGIを書いてますが、それをCに書き換えています。 今のところフォームをデコードして、nameを入れるとvalueを返す関数をつくって、さあこれから、という状況です。 基本的な質問ですが、Cには文字列の置換をしてくれる関数ってありますか? たとえば、標準のライブラリに入ってなくても、どっかからダウンロードできるとか。 なければstring.hに入っている関数を使って自分で作ろうかと思ってますが、作った後に、“xxxxをつかったら一発でできるじゃん”という発見がすごいショックで、今までもなんどもありましたので、おたずねします。 よろしくお願いします。

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

  • ベストアンサー
  • gimmick
  • ベストアンサー率49% (134/270)
回答No.5

> これでなぜ漢字コード非対応なのかがよくわかりません。 置き換えられる対象文字(substr1)が1バイト文字1文字ではなく、2文字以上もしくは2バイト文字だったら文字コードが重なる可能性が少なくて、strstrでも2バイト文字の1バイト部分を切ったりしないと考えて大丈夫ですか? この点については漢字コードの種類に依存します。例えばシフトJISの場合、2バイトのうちの1バイト目と2バイト目のコードの範囲は重なっています。このため、ある漢字1文字をsubstr1に指定した場合、2文字続く2バイト文字(全4バイト)の中央の2バイトが置換されてしまう可能性があります。また、一般には2バイト文字は1バイト文字と混在しているので、問題はさらに複雑になります。私はあまり詳しくないのですが、シフトJIS以外の漢字コードも同様の問題を抱えていると思います。

nak205
質問者

お礼

ありがとうございました。 いろいろ試してみます。 ほんとに参考になりました。 またお願いします。

その他の回答 (4)

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.4

#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); /*最後の部分のコピー*/

nak205
質問者

補足

ありがとうございます。 大変参考になります! これでなぜ漢字コード非対応なのかがよくわかりません。 置き換えられる対象文字(substr1)が1バイト文字1文字ではなく、2文字以上もしくは2バイト文字だったら文字コードが重なる可能性が少なくて、strstrでも2バイト文字の1バイト部分を切ったりしないと考えて大丈夫ですか? もしよろしければご回答よろしくお願いします。

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.3

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)
回答No.2

こんにちわ。 strstr 関数で、置換する文字列を検索して、strcpy 関数で 該当箇所にコピーすればOk だと思います。

nak205
質問者

補足

早速ありがとうございます。 やっぱり、一発で置換してくれる関数はないということですね。 strstrとstrcpyを使った場合、'\n'を"<br>"で置き換えたい場合は元の文字列と、処理後の文字列の長さが変わってしまうので、別の文字列にコピーしていったほうがいいいでしょうか?

  • kmor
  • ベストアンサー率27% (225/825)
回答No.1

すみません、今手元に資料がないので詳細はわかりません。 ポインタとstrcpy関数を使えば出来ます。 strcpyのパラメタの詳細を忘れてしまったので。 多分 char * strcpy(char * コピー先, char * コピー元) だったような気がします。

関連するQ&A

  • Perlのファイル操作の置換について

    Perlを利用し、ファイル内の置換操作を行いたいと思います。Perlに関して全く無知なので誰か教えてください。 変換したい内容を下に記載します。 (1)html:button value="aaa" name="bbb" c:button property="${aaa.bbb}"                      ↓↓  (2)html:button value="aaa" name="bbb" c:button property="${aaa.bbb}" 上記の変換ではvalueとnameがpropertyになる (3)html:button value="xxx" var="yyy"        ↓↓ (4)c:button prop="xxx" id="yyy" (3)に関してはvalueとvarの間に何か他の処理が入ってもvalueとvarだけを特定し、変換できるScript文にしたいです。 言葉足らずだったらすみません。誰か教えて下さい。

    • ベストアンサー
    • Perl
  • 文字単位の置換

    perlの $string=~tr/abc/xyz/; ($stringの中の"a"を"x","b"を"y""c"を"z"に置換) と同じことをphpでやりたいのですが、 できますでしょうか。 よろしくお願いします。

    • 締切済み
    • PHP
  • C#でも文字列操作について

    string sFileNM = "c:\data\2003\12\xxxxxx.csv"; 上記の「xxxxxx.csv」を「zzzzzz.txt」に置換したいのですが、VBだとright関数とか文字操作関数で可能ですが、C#の場合には、どうすれば可能でしょうか? 宜しくお願いします。

  • 文字列を任意の場所で分割(split)したい

    CでCGIを書く上で、perlのsplit命令の代替になるようなライブラリを探しています。 www=xxx&yyy=zzz という引数をchar型の配列に入れ、それを & で分割し、次に = で分割して query[0].name = www; query[0].value = xxx query[1].name = yyy; query[1].value = zzz などと、perlと同等のことをさせたいのですが、文字列をその都度走査していたのでは処理が莫大になりそうなので、もしご存知であれば教えていただければと思います。

  • 文字列の置換

    JAVAであるファイル内の文字列を置換するプログラム(日本語)を作りたいのですが、 ・ ・ String h_s; FileReader h_fr = new FileReader(in_filename); BufferedReader h_br = new BufferedReader(h_fr); while(true){  h_s = h_br.readLine();  if (h_s == null){   break;  }  ●文字列を置換するプログラム● } ・ ・ ここの●文字列を置換するプログラム●にあたる適当な関数って何かありますか? たとえばperlでいうと↓みたいなものなのですが・・・ s/置換前文字/置換後文字/g よろしくお願いします。

    • ベストアンサー
    • Java
  • 条件を指定しての置換

    Perlでの文字置換の質問です。以下のように文字列があった場合に +AAA a01 name +BBB b01 name +CCC c01 name +DDD d01 name ・ ・ +CCCと+DDDの間にあるnameの文字のみaddressに置換したい時は どのようにPerlで記述したらよろしいでしょうか。 全てのnameがaddressになってしまい困っています。 よろしくお願いします。 完成形↓ +AAA a01 name +BBB b01 name +CCC c01 address +DDD d01 name

  • フォームデコード

    %80などのURLデコードを探しています。 Perlのフォームデコードは分かりますが、PHP版のものを 教えてください。 PHPではtrの置換が使えないんですよね。

    • 締切済み
    • PHP
  • 入力したテキストを置換するプログラミングを作りたいのですが上手くいかず

    入力したテキストを置換するプログラミングを作りたいのですが上手くいかず困っています。 テキストエリアに文章を入力し、 次に置換前の文字と置換後の文字をそれぞれ入力する形にして置換をしようと考えています。 最終的に置換前の文字と置換後の文字を入力する欄を複数用意して 複数の置換を一度で行ないたいと思っています。 ですが下記の「a1」に入力した置換前の文字全て削除され「a2」の内容に変換されません。 初心者なので根本的に間違ってるかもしれませんが、わかる方よければ教えてください。 ----------------- <form method="post" action="form.cgi"> <textarea name="chikan" rows="10" cols="70"></textarea><br> <input type="text" name="a1" size="50">を<input type="text" name="a2" size="50">に変換<br><br> </p> <p><input type="submit" value="置換"></p> </form> ----------------- ----------------- #!/usr/local/bin/perl if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $alldata, $ENV{'CONTENT_LENGTH'}); } else { $alldata = $ENV{'QUERY_STRING'}; } foreach $data (split(/&/, $alldata)) { ($key, $value) = split(/=/, $data); $value =~ s/\+/ /g; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; $value =~ s/\t//g; $value =~ s/\n//; $in{"$key"} = $value; $in{'chikan'} =~ s/\Q$in{'a1'}\E/$in{'a2'}/g; } print"Content-type: text/html\n\n"; print <<"EOM"; <html> <head><title></title> </head> <body> <textarea name=area rows=50 cols=70> $in{'chikan'} </textarea> </form> </body> </html> EOM exit; -------------------------

    • ベストアンサー
    • CGI
  • FORMからの入力をCで受け取ってデコードしたい!

    はじめまして。 現在C++でCGIを作成しております。 特にFORMからの入力をC++で処理したいと考えているのですが、 FORMからの入力は『BBS_Message=%83A%83C%83E%83G%83I%83J』のようになっており、ank文字以外が変換されて しまいます。 Perlとかだとコマンド一発?で変換できるみたいなのですが、 C++とかでこれをデコードする何かよい用法がないでしょううか? だれかが変換ライブラリとかを作成していないものなのでしょうか? 自分で変換できないこともないですが、とても大変なので、よい方法を知っておられるかたが、 いらっしゃいましたらご教授願います。 それができないからCGIはParlが大半なのでしょうかね?

    • ベストアンサー
    • CGI
  • あったらいいなと思う、C文字列ライブラリ関数

    みなさんC言語で開発してきた中で、ライブラリとして用意されてたら いいなと思った事のある関数・処理としてどのようなものがありますでしょうか。 特定業務向けの話でなく、汎用的な処理ででも結構です。 例えば、いつも思うのが、なんで文字列A中の文字列Bを、文字列Cに置換する 関数ってなんでないんだろう、などですかね。 (そりゃstrstr、strcatなど既存ライブラリ関数を使いまわせば書けますが...)