• ベストアンサー

文字変換プログラム

char sA, sB; sA = "晴れ"; sB = "曇り"; C言語でprintf("今日は%sです。明日は%sです。", sA, sB); というようなものがありますが、 今日は%aです。明日は%bです。のようにして、%a,%bに 先に指定しておいた文字を入れるような関数を作りたいと思っております。 一文字一文字を調べて該当のものがあれば変換して、という方法を 考えていましたが、置換処理プログラムを参考にしても同じような 関数ができるのではないか・・・と今考えております。 どのようにしていくのが一番確実な処理ができるでしょうか。 よろしくおねがいいたします。 環境はC++Builder6です。

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

  • ベストアンサー
回答No.5

   こういうのかな? #include <stdio.h> void foo(char *format, char *s0, char *s1) { int i; i = 0; while(*(format + i) != '\0'){ if(*(format + i) == '#'){ switch(*(format + i + 1)){ case '0': printf("%s", s0); break; case '1': printf("%s", s1); break; } i ++; } else putchar(*(format + i)); i ++; } } int main(void) { char *s0 = "晴れ", *s1 = "曇り"; foo("今日は、#0後#1、明日は、#0時々#1、明後日は、#0です。", s0, s1); return 0; }  

すると、全ての回答が全文表示されます。

その他の回答 (10)

  • akanekor
  • ベストアンサー率52% (102/194)
回答No.11

>No9 今回の仕様だと 検索対象文字列"%a","%b"みたいな半角文字列ですから、別にPOSでも問題無く動きますよ。 後、今時、用意されている文字列用クラスやSTL使わずに、 (速度)効率なんて、、。 今は、顧客からよっぽど速度をもとめられないかぎり ソースの可視性と簡易性の方が重要ですよ。 まあ、背景的な仕様を質問者が言っていないので、 速度優先、可視性優先かは それ次第なんですけどね(==;

Caya
質問者

お礼

皆様回答ありがとうございました。 色々な回答をしていただき、それぞれのマイナス面、プラス面を教えていただき、その上で考えたいと思っておりました。 主に、詳しく方法を回答いただきましたように、 関数を全て自分で作るのと、検索関数を使用して変換するのとがやはり あるのだと思いました。 今回は変換する文字列がないことも多くあるので、その文字列を検索する処理が 無駄になる事があるので、文章を一文字一文字おっていく関数を 自作する事にしました。 ありがとうございました。

すると、全ての回答が全文表示されます。
  • dra2jp
  • ベストアンサー率25% (18/72)
回答No.10

KoHal >他の方の回答にレスをするのは規約違反なので、この回答は削除されるはずです(大笑い。 何を大笑いしているのかわかりませんね。

すると、全ての回答が全文表示されます。
  • KoHal
  • ベストアンサー率60% (110/181)
回答No.9

他の方の回答にレスをするのは規約違反なので、この回答は削除されるはずです(大笑い。 >No.8の方の回答で示されたTipsに関して。 AnisString::Posはマルチバイト文字に対応してません。 日本語を扱うならAnsiString::AnsiPosを使う必要があります。こちらがマルチバイト文字対応版。 あと、複数の文字列を一括して変換するのであれば、AnsiString::Dlete, Insertを使うのは効率が悪いです。 しかし、「何がもっとも効率的か?」を判断するには、質問者が要求する関数の仕様が明確になっている必要があるわけで、結局はNo.2の方の回答の「仕様を明確にせよ」に戻ってしまいます。 質問者が仕様を明確にしない以上、回答者が集まってあれこれ言うても仕方がないわけです。 質問者はどうしたんでしょうね? もう見てないのかな?

すると、全ての回答が全文表示されます。
  • akanekor
  • ベストアンサー率52% (102/194)
回答No.8

せっかく、C++Builder6使ってるのなら、AnsiStringつかってくださいな 文字列領域等の面倒な事考えなくてすむから、楽ですよ。 文字置換のいい例があったので、どうぞ。 http://www.geocities.co.jp/SiliconValley/4805/bcbtips/bcbtips079.htm ちなみに、AnsiString Class http://homepage1.nifty.com/emil/ansistring.html

すると、全ての回答が全文表示されます。
回答No.7

まず、strstr() という関数を調べてください。 たとえば、strstr(str, "%a"); は、(あれば) str の中にある最初の "%a" の位置のポインタを返します。 この部分を、置き換えるべき文字と差し替えればいいわけです。ただし、元の文字("%a") と、置き換わる文字("晴れ")の長さが違うので、その点の取り扱いに考慮が必要です。 そして、文字列の処理には、sprintf が有効です。 たとえば、 char src[1024]; // この中に元々の文字列がある char dest[1024]; // %a を "晴れ" に差し替える char *ptr; // %a を探す ptr = strstr(src, "%a"); if (ptr) // 文字があれば、 { char *ushiro; *ptr = '\0'; // %a の場所で文字列を分ける ushiro = ptr + strlen("%a"); // ここが後半の文字列のスタート位置 (文字列の検出位置+その長さ) sprintf(dest, "%s晴れ%s", ptr, ushiro); // 前半+晴れ+後半 で文字列を作る sprintf(src, "%s", dest); // 次の処理のために、変換済みの文字列を src に下記戻しておく } ひとつの文字列の中に、複数の %a が出現する可能性があるので、実際には、if (ptr) ではなく、while() で、「文字が見つかる限り」というループにします。 また、"%a" の部分を、"%b", "%c" ... などに適用するように、この部分もループにするといいでしょう。 置換文字列は、構造体を使って、 struct { char *src; char *dest; } table[] = { {"%a", "晴れ"}, {"%b", "曇り"}, {0, 0} }; などという形で整理するとよいのですが。 あと、Cの、それも、printf() 系の関数で、% がある意味で使われているのは、printf() 系のローカルな事情ですから、他のアプリケーションのデータ(多分、そのアプリケーションのテンプレート)の中に、%a で置き換えるような処理があっても、問題はないでしょう。

すると、全ての回答が全文表示されます。
回答No.6

 ちょっと修正。 #include <stdio.h> void foo(const char *format, const char *s0, const char *s1) { int i; for(i = 0; *(format + i) != '\0'; i ++){ if(*(format + i) == '#'){ switch(*(format + i + 1)){ case '0': printf("%s", s0); break; case '1': printf("%s", s1); break; } i ++; } else putchar(*(format + i)); } return; } int main(void) { char *s0 = "晴れ", *s1 = "曇り"; foo("今日は、#0後#1、明日は、#0時々#1、明後日は、#0です。", s0, s1); return 0; }  

すると、全ての回答が全文表示されます。
  • dra2jp
  • ベストアンサー率25% (18/72)
回答No.4

う~ん、%aで文字列を表示させたる関数を自作したいという風に見えますけど、Cでは文字列は%sで表示させると言うルールがあります。 関数を自作するというのはえらい人が作ったライブラリなどにありますが、 %なんとかっていうのは演算子であってこれはC言語の決まりですからC言語のルールを無視したいのでしたら 自分で新しい言語を作る必要があるのでは。 >先に指定しておいた文字を入れるような関数を作りたいと思っております。 >一文字一文字を調べて該当のものがあれば変換して、 全然意味がわかりません。 もう少し詳しくお願いします。

すると、全ての回答が全文表示されます。
  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

C言語における % の意味を知らないままご質問されているものと思います。% は、(剰余を求める演算子以外に)stdio.hで定義されているprintf系の関数の出力書式を指定するために使用します。ですので、%a, %b という書き方はおかしな書き方で、大きな誤解を生むおそれがあります。 さて、ご質問の「先に指定しておいた文字を入れるような関数」ですが、具体的なイメージがわきません。 ユーザに「今日は晴れです。明日は曇りです。」と入力してもらって、そこから「晴れ」「曇り」の天気の部分だけ抜き出してくることを想定されているのでしょうか? 仮にそうなら、この天気の部分に入る可能性のある語句には何か制限があるでしょうか?(例えば、「今日は天丼です。明日はカツ丼です。」という入力を考慮するのでしょうか?) <それが、仕様を明確にする、ということです。

すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> どのようにしていくのが一番確実な処理ができるでしょうか。 一番確実な方法を見つけるには、まず仕様を明確にしなければなりません。詳細な仕様を補足してください。 もう一点、 > 環境はC++Builder6です。 とのことですが、C++ではなくCを使うのですね。

すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

この用途なら、関数sprintf()で十分では。

参考URL:
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/printf.3.html
Caya
質問者

お礼

アドバイスありがとうございます。 いえ、関数を作らなくてはならないのです。 質問内容が足らなかったかもしれません。 %aの型ならば、日付、%bの方ならば、英数字のみの文字列、のような感じで、 %a型には、07/25、%b型には、 111aaa、のように指定する事を決めておいて、 実際の文章では、%aのみしか使われなかったり、sprintfでは ("%s%s", cA, cA)と、きちんと順番どおりに2個指定しておかなければなりませんが、関数では %a%a と 表示する際に、%a があれば、7/25を表示する、という指定のみで、どこにいくつあっても表示してやらなくてはなりません。 質問がうまくできていなかったと思いますが、再度よろしくお願いいたします。

すると、全ての回答が全文表示されます。

関連するQ&A