-1

C/C++ 用のPHP のようなstr_replace()を探していましたが、結果のバッファを割り当て/再割り当てするソリューションしか見つかりませんでした。組み込み環境では、常に可能とは限りません。文字列用のメモリがないか、malloc()さえありません。だから私はstrncat()に似た同じバッファを使用する関数を探しています。バッファサイズはパラメータとして与えられます:

 void str_replace(char* search,char* replace,char* subject,int maxBufferSize);

トリックは、私が 1 分以内に投稿する 1 つを書いたということです。はい、これは私自身の質問に答える典型的なケースですが、合法であることを読みました

とにかく、ベストアンサーの承認ボタンを押します。私のソリューションはテスト済みで、うまく機能することを願っていますが、改善の余地があります。より良い答えがあるでしょう、私は確信しています。私は待つことができる。

4

2 に答える 2

2

テストされていない私の試みは次のとおりです。

void str_replace(char *search, char *replace, char *subject, size_t size)
{
    char *end = subject+size;
    size_t sl = strlen(search);
    size_t rl = strlen(replace);
    size_t l = strlen(subject);
    char *src = memmove(end-l-1, subject, l+1);
    char *dest = subject;
    while (*src) {
        char *match = strstr(src, search);
        if (!match) {
            match = src + strlen(src);
            rl = 0;
        }
        memmove(dest, src, match-src);
        dest += match-src;
        src = match+sl;
        memcpy(dest, replace, rl);
        dest += rl;
    }
    *dest = 0;
}

これは、 を想定してstrlen(replace) <= strlen(search)います。destその制約が満たされない場合は、合格しないことsrc、および置換が所定の位置にコピーされたときに適合することを確認するために、いくつかの追加のチェックが必要です。

このアルゴリズムは、過剰なアクセス (読み取りと書き込み) を回避するために最適に近いはずです。

于 2013-02-01T20:43:27.127 に答える
0

だから、ここに私の簡単な解決策があります。動作しますが、問題があります:

  • パターンが複数回見つかった場合、残りの部分 (縮小/拡大) が各ラウンドでコピーされます。
  • memcpy()を使用する必要があります。
  • forステートメントの外で事前計算を行う必要があります。

編集: リクエストにコメントが追加されました。

    void strReplace(char* pattern,char* replacement,char* buffer,int maxLength) {

      int buflen = strlen(buffer);  // atual string length (changes after each replace)
      int patlen = strlen(pattern);  // pattern length, constant
      int replen = strlen(replacement);  // replacement lengh, constant
      int matlen = (patlen < replen ? patlen : replen);  // length of pattern/replacement mathcing part
      int ptr = 0;  // pointer, runs from 0 to buffer length

      while (true) {

        // find out, if string at buffer[ptr] matches the pattern
        int match = true;
        for (int n = 0; n < patlen; n++) {
          if ((n + ptr) == buflen) return;
          if (buffer[n + ptr] != pattern[n]) {
            match = false;
            break;
          } // if matching
        } // for pattern

        // if not match, increase ptr
        if (!match) {
          ptr++;
          if (ptr > buflen) return;
          continue;
        } // if not match

        // replace the common part (which requires no remaining block move)
        for (int n = 0; n < matlen; n++) buffer[n + ptr] = replacement[n];
        // if we're lucky, the search string is same lenght as replacement
        if (patlen == replen) return;

        // move remaining
        if (patlen > replen) {  // shrink, if repacement was shorter

          int shrink = patlen - replen;
          // perform shrink
          for (int idx = matlen + ptr; idx < buflen - shrink; idx++) {
            buffer[idx] = buffer[shrink + idx];
          }
          // don't forget to close the asciiz string
          buffer[buflen - shrink] = 0;

          // align ptr
          ptr = 1 + ptr - shrink;
          // align buffer
          buflen -= shrink;

        } else {   // expan if replacement is longer

          int expand = replen - patlen;
          int bufend = buflen + expand;  // buffer end after expand
          if (bufend > maxLength - 1) bufend = maxLength - 1;  // apply maxLength

          // make room by copying remaining to the end of the string
          for (int idx = bufend; idx > ptr + matlen + expand; idx--) {
            buffer[idx - 1] = buffer[idx - 1 - expand];
          }
          // fill the hole with the remainig part of the replacement
          for (int n = matlen; n < replen; n++) {
            buffer[n + ptr] = replacement[n];
          }
          // don't forget to close the asciiz string
          buffer[bufend] = 0;

          // align ptr
          ptr = 1 + ptr + expand;
          // align buffer
          buflen = bufend;

        } // if shrink else expand

        // continue from new ptr

      } // scan buffer

    } // strReplace()
于 2013-02-01T19:36:03.477 に答える