6

重複の可能性:
C で文字列を置換する関数は何ですか?

文字列内の特定の文字を複数の文字に置き換えようとしています。これが私がやろうとしていることの例です。

「aaabaa」という文字列があるとします

文字「b」の出現箇所をすべて 5 つの「c」に置き換えたいと考えています。

終わったら「あああああ」が「あぁっっっっっっっっっっっっっっっっ」」

私は次のコードを書きました:

#include <stdio.h>
#include <string.h>
int main(void)
{
    char s[20] = "aaabaa";
    int i, j;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            for (j=0; j<5; j++)
            {
                s[i+j] = 'c';
            }
        }
    }
    printf("%s\n", s);
}

この関数からの私の出力は「aacccccc」です。最後の 2 つの a を c で上書きしているように見えます。これらの最後のいくつかの a が上書きされないようにする方法はありますか?

4

7 に答える 7

10

バッファのサイズを気にせずにこれを一般的に行いたい場合はmalloc、結果を保持するのに十分な大きさの新しい文字列を作成する必要があります。

/* return a new string with every instance of ch replaced by repl */
char *replace(const char *s, char ch, const char *repl) {
    int count = 0;
    const char *t;
    for(t=s; *t; t++)
        count += (*t == ch);

    size_t rlen = strlen(repl);
    char *res = malloc(strlen(s) + (rlen-1)*count + 1);
    char *ptr = res;
    for(t=s; *t; t++) {
        if(*t == ch) {
            memcpy(ptr, repl, rlen);
            ptr += rlen;
        } else {
            *ptr++ = *t;
        }
    }
    *ptr = 0;
    return res;
}

使用法:

int main() {
    char *s = replace("aaabaa", 'b', "ccccc");
    printf("%s\n", s);
    free(s);
    return 0;
}
于 2012-10-15T06:03:27.010 に答える
5

あなたの問題は、「cccccc」を元の文字列に置き換えて、置き換えたい文字の後の残りの文字を上書きすることです...新しい文字列にコピーし、2 つのインデックス (それぞれに 1 つずつ) を追跡する必要があります。

そして、元の文字列のサイズに置換値を加えたサイズよりも大きいと宣言したことに満足してくださいchar s[20]。そうしないと、重要なログイン システムでバッファ オーバーフローの脆弱性が作成されていたでしょう :-)

乾杯、

于 2012-10-15T05:59:30.810 に答える
1

2 番目の char 配列を宣言する必要があります。以下のコードでは、条件が失敗したときに配列 s の内容を s1 にコピーするだけです。

#include <stdio.h>
#include <string.h>
int main(void)
{
  char s[20] = "aaabaa";
  char s1[1024];
  int i, j, n;
  for (i=0, n = 0; s[i]!= '\0'; i++)
  {
    if (s[i] == 'b')
    {
        for (j=0; j<5; j++)
        {
            s1[n] = 'c';
            n++;
        }
    }
    else
    {
        s1[n] = s[i];
        n++;
    }
}
s1[n] = '\0';
printf("%s\n", s1);
}
于 2012-10-15T06:07:08.170 に答える
1

別の変数を使用できます

#include <stdio.h>
#include <string.h>
int main(void)
{
    char s[20] = "aaabaa";
    char temp[20]="";
    int i, j,k;
    k=0;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            for (j=0; j<5; j++)
            {
                temp[k] = 'c';
                k++;
            }
        }
        else
        {
            temp[k]=s[i];
            k++
        }
    }
    printf("%s\n", temp);
}
于 2012-10-15T06:09:34.580 に答える
1
#include <stdio.h>
#include <string.h>

int main(void)
{
    char temp[20];
    char s[20] = "aaabaa";
    int i, j;
    for (i=0; s[i]!= '\0'; i++)
    {
        if (s[i] == 'b')
        {
            strcpy(temp,s[i+1]); //copy rest of the string in this case 'aa'
            for (j=0; j<5; j++)
            {
                s[i+j] = 'c';
            }
            s[i+j] = '\0';   // here we get s = "aaaccccc"
            strcat(s,temp); // concat rest of the string (temp = "aa") after job is done. 
                           //  to this point s becomes s = "aaacccccaa"
        }
    }
    printf("%s\n", s); //s = "aaacccccaa". 
}

ここでは、バッファー (temp) を使用して、置換対象の文字の後の残りの文字列を格納しています。置換が完了したら、最後に追加します。

s = "aaacccccaa" となります。

于 2012-10-15T08:53:15.400 に答える
0

配列を動的に割り当てる場合は、おそらく 2 つ目の配列を割り当てる必要があります。文字列 s には固定量のメモリしか割り当てられていないため、これが必要です。

したがって、for ループ内の文字を上書きしようとする代わりに、新しい配列の大きさを示すカウンターをインクリメントすることをお勧めします。カウンターは元の文字列のサイズから始まり、「b」のインスタンスが見つかるたびに 4 ずつ増加します。次に、変更された文字列を size[counter] の新しい char バッファに適切にコピーし、'b' が見つかるたびに 5 つの c を挿入する関数を作成できるはずです。

于 2012-10-15T06:01:35.073 に答える
-1

この機能を使用します:

char *replace(char *st, char *orig, char *repl) {
  static char buffer[4096];
  char *ch;
  if (!(ch = strstr(st, orig)))
   return st;
  strncpy(buffer, st, ch-st);  
  buffer[ch-st] = 0;
  sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
  return buffer;
  }

あなたの場合:printf("%s\n", replace(s,"b","ccccc"));

于 2012-10-15T05:57:56.130 に答える