Apa fungsinya untuk menggantikan substring dari string di C?
96
Diberikan char *string ( ), saya ingin mencari semua kemunculan substring dan menggantinya dengan string alternatif. Saya tidak melihat ada fungsi sederhana yang mencapai ini di <string.h>.
saya ragu Anda dapat melakukan ini dengan cara yang bisa berubah
user44511
Jawaban:
90
Pengoptimal harus menghilangkan sebagian besar variabel lokal. Penunjuk tmp ada di sana untuk memastikan strcpy tidak harus menjalankan string untuk menemukan null. tmp menunjuk ke akhir hasil setelah setiap panggilan. (Lihat algoritma Shlemiel pelukis untuk mengapa strcpy bisa mengganggu.)
// You must free the result if result is non-NULL.char *str_replace(char *orig, char *rep, char *with){
char *result; // the return stringchar *ins; // the next insert pointchar *tmp; // variesint len_rep; // length of rep (the string to remove)int len_with; // length of with (the string to replace rep with)int len_front; // distance between rep and end of last repint count; // number of replacements// sanity checks and initializationif (!orig || !rep)
returnNULL;
len_rep = strlen(rep);
if (len_rep == 0)
returnNULL; // empty rep causes infinite loop during countif (!with)
with = "";
len_with = strlen(with);
// count the number of replacements needed
ins = orig;
for (count = 0; tmp = strstr(ins, rep); ++count) {
ins = tmp + len_rep;
}
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result)
returnNULL;
// first time through the loop, all the variable are set correctly// from here on,// tmp points to the end of the result string// ins points to the next occurrence of rep in orig// orig points to the remainder of orig after "end of rep"while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result;
}
@jmucchiello: gunakan size_tsebagai pengganti intukuran objek / string arbitrer dan indeks ke dalamnya. Juga, apa tujuan strcpy(tmp, orig);akhirnya? Sepertinya salah.
Alexey Frunze
@Alex, strcpy terakhir (tmp, orig) menyalin bagian terakhir string ke tujuan. Misalnya: ganti ("abab", "a", "c") di akhir pengulangan, hasil berisi, "cbc" dan orig menunjuk ke "b" terakhir di "abab". Strcpy terakhir menambahkan "b" sehingga string yang dikembalikan adalah "cbcb". Jika tidak ada yang tersisa untuk disalin, orig harus mengarah ke ASCIIZ dari string input.
jmucchiello
penyederhanaan: Anda dapat mengganti forloop pertama dengan for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, kemudian tmphanya digunakan untuk menulis.
Berhati-hatilah bahwa fungsi ini mengembalikan NULL jika tidak ada kejadian untuk diganti (if (! (Ins = strstr (orig, rep))) return NULL;). Anda tidak bisa hanya menggunakan output, Anda perlu memeriksa apakah outputnya NULL dan jika demikian gunakan string asli (jangan hanya menyalin pointer ke string hasil karena free (result) kemudian membebaskan string asli). Penggunaannya lebih mudah jika string input disalin ke string output jika tidak ada yang diganti.
Adversus
18
Ini tidak tersedia di pustaka C standar karena, dengan hanya diberi karakter * Anda tidak dapat menambah memori yang dialokasikan ke string jika string pengganti lebih panjang dari string yang diganti.
Anda dapat melakukan ini dengan lebih mudah menggunakan std :: string, tetapi bahkan di sana, tidak ada fungsi tunggal yang akan melakukannya untuk Anda.
1 / strlen (char *) + 1 belum tentu sama dengan ukuran penyimpanan. 2 / Ada banyak versi N dari fungsi string yang menerima dan parameter ukuran buffer tambahan sehingga tidak ada alasan mengapa tidak ada snreplace (). 3 / Mungkin ada fungsi ganti di tempat dan bukan fungsi ganti di tempat. 4 / Menurut Anda bagaimana sprintf bekerja? Ini diberi argumen char * dan tidak perlu meningkatkan alokasi memori darinya, jadi tidak ada alasan penggantian tidak dapat berfungsi juga ... (meskipun C memiliki desain "string" yang buruk, dan ukuran buffer harus selalu diteruskan dengan pointer => snprintf)
Steven Spark
12
Tidak ada satupun.
Anda harus menggulungnya sendiri menggunakan sesuatu seperti strstr dan strcat atau strcpy.
Di mana koleksi kipas dari fungsi yang sering digunakan disimpan? Tentunya sudah ada perpustakaan untuk itu ....
Pacerier
1
strcat()adalah saran yang buruk.
Iharob Al Asimi
11
Anda dapat membangun fungsi replace Anda sendiri menggunakan strstr untuk menemukan substring dan strncpy untuk disalin sebagian ke buffer baru.
Kecuali jika Anda ingin replace_withmemiliki panjang yang sama dengan yang Anda inginkan replace, mungkin yang terbaik adalah menggunakan buffer baru untuk menyalin string baru.
Karena string di C tidak dapat tumbuh secara dinamis di tempat, substitusi umumnya tidak akan berfungsi. Oleh karena itu Anda perlu mengalokasikan ruang untuk string baru yang memiliki cukup ruang untuk substitusi Anda dan kemudian menyalin bagian-bagian dari aslinya ditambah substitusi ke string baru. Untuk menyalin bagian-bagian Anda akan menggunakan strncpy .
Ukuran buffer bisa lebih besar dari strlen, string pengganti bisa lebih kecil dari string yang diganti ... oleh karena itu Anda tidak perlu mengalokasikan memori untuk melakukan replace. (Juga pada mikrokontroler Anda mungkin tidak memiliki memori tak terbatas, dan Anda mungkin perlu melakukan penggantian di tempat. Salin semuanya ke buffer baru mungkin bukan solusi yang tepat untuk semua orang ...)
Steven Spark
8
Berikut beberapa contoh kode yang melakukannya.
#include<string.h>#include<stdlib.h>char * replace(
charconst * const original,
charconst * const pattern,
charconst * const replacement
){
size_tconst replen = strlen(replacement);
size_tconst patlen = strlen(pattern);
size_tconst orilen = strlen(original);
size_t patcnt = 0;
constchar * oriptr;
constchar * patloc;
// find how many times the pattern occurs in the original stringfor (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
{
patcnt++;
}
{
// allocate memory for the new stringsize_tconst retlen = orilen + patcnt * (replen - patlen);
char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) );
if (returned != NULL)
{
// copy the original string, // replacing all the instances of the patternchar * retptr = returned;
for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen)
{
size_tconst skplen = patloc - oriptr;
// copy the section until the occurence of the patternstrncpy(retptr, oriptr, skplen);
retptr += skplen;
// copy the replacement strncpy(retptr, replacement, replen);
retptr += replen;
}
// copy the rest of the string.strcpy(retptr, oriptr);
}
return returned;
}
}
#include<stdio.h>intmain(int argc, char * argv[]){
if (argc != 4)
{
fprintf(stderr,"usage: %s <original text> <pattern> <replacement>\n", argv[0]);
exit(-1);
}
else
{
char * const newstr = replace(argv[1], argv[2], argv[3]);
if (newstr)
{
printf("%s\n", newstr);
free(newstr);
}
else
{
fprintf(stderr,"allocation error\n");
exit(-2);
}
}
return0;
}
Itu repl_str () di creativeandcritical.net cepat dan dapat diandalkan. Juga disertakan di halaman itu adalah varian string lebar, repl_wcs () , yang dapat digunakan dengan string Unicode termasuk yang dikodekan dalam UTF-8, melalui fungsi pembantu - kode demo ditautkan dari halaman. Pengungkapan penuh terlambat: Saya adalah penulis halaman itu dan fungsi di dalamnya.
cepat dan andal, tetapi memiliki kebocoran memori yang besar.
MightyPork
3
Saya tidak melihat bagaimana itu bisa. Hanya ada satu malloc dan penelepon diperintahkan untuk mengosongkan memori saat tidak lagi diperlukan. Bisakah kamu lebih spesifik?
Laird
@Lairdpos_cache = realloc(pos_cache
PSkocik
@PSkocik Fungsi telah ditingkatkan sejak keluhan oleh @MightyPork tetapi meskipun sekarang memiliki malloc / realloc tambahan untuk pos_cache, saya tidak dapat melihat jalur kode yang menghindari free(pos_cache);fungsi di akhir.
Laird
@Lantas reallocmungkin gagal. Jika ya, itu kembali NULLdan meninggalkan penunjuk lama utuh. p = realloc(p, x)akan, jika gagal, menulis ulang penunjuk heap yang valid pdengan NULL, dan jika itu padalah satu-satunya referensi Anda ke objek heap tersebut, Anda telah membocorkannya. Ini kesalahan pemula yang klasik.
PSkocik
3
saya menemukan sebagian besar fungsi yang diusulkan sulit dipahami - jadi saya datang dengan ini:
staticchar *dull_replace(constchar *in, constchar *pattern, constchar *by){
size_t outsize = strlen(in) + 1;
// TODO maybe avoid reallocing by counting the non-overlapping occurences of patternchar *res = malloc(outsize);
// use this to iterate over the outputsize_t resoffset = 0;
char *needle;
while (needle = strstr(in, pattern)) {
// copy everything up to the patternmemcpy(res + resoffset, in, needle - in);
resoffset += needle - in;
// skip the pattern in the input-string
in = needle + strlen(pattern);
// adjust space for replacement
outsize = outsize - strlen(pattern) + strlen(by);
res = realloc(res, outsize);
// copy the patternmemcpy(res + resoffset, by, strlen(by));
resoffset += strlen(by);
}
// copy the remaining inputstrcpy(res + resoffset, in);
return res;
}
Anda dapat menggunakan fungsi ini (komentar menjelaskan cara kerjanya):
voidstrreplace(char *string, constchar *find, constchar *replaceWith){
if(strstr(string, replaceWith) != NULL){
char *temporaryString = malloc(strlen(strstr(string, find) + strlen(find)) + 1);
strcpy(temporaryString, strstr(string, find) + strlen(find)); //Create a string with what's after the replaced part
*strstr(string, find) = '\0'; //Take away the part to replace and the part after it in the initial stringstrcat(string, replaceWith); //Concat the first part of the string with the part to replace withstrcat(string, temporaryString); //Concat the first part of the string with the part after the replaced partfree(temporaryString); //Free the memory to avoid memory leaks
}
}
Ganti pola terlepas dari apakah panjang atau pendek.
Tidak menggunakan malloc apa pun (eksplisit atau implisit) untuk menghindari kebocoran memori secara intrinsik.
Ganti sejumlah kemunculan pola.
Toleransi ganti string yang memiliki substring sama dengan string pencarian.
Tidak harus memeriksa apakah Line array cukup besar untuk menampung penggantinya. misalnya Ini tidak bekerja kecuali pemanggil mengetahui bahwa ukuran baris cukup untuk menampung string baru.
strrep (Ganti String). Mengganti 'strf' dengan 'strr' di 'cadena' dan mengembalikan string baru. Anda perlu membebaskan string yang dikembalikan dalam kode Anda setelah menggunakan strrep.
Parameter cadena String dengan teks. strf Teks untuk ditemukan. strr Teks pengganti.
perbaikan respons fann95, menggunakan modifikasi string di tempat, dan mengasumsikan buffer yang ditunjukkan oleh baris cukup besar untuk menahan string yang dihasilkan.
staticvoidreplacestr(char *line, constchar *search, constchar *replace){
char *sp;
if ((sp = strstr(line, search)) == NULL) {
return;
}
int search_len = strlen(search);
int replace_len = strlen(replace);
int tail_len = strlen(sp+search_len);
memmove(sp+replace_len,sp+search_len,tail_len+1);
memcpy(sp, replace, replace_len);
}
Exmaple Usage
char s[]="this is a trial string to test the function.";
char x=' ', y='_';
printf("%s\n",zStrrep(s,x,y));
Example Output
this_is_a_trial_string_to_test_the_function.
EDIT: @siride benar, fungsi di atas hanya menggantikan karakter. Baru aja yang ini, yang menggantikan string karakter.
#include<stdio.h>#include<stdlib.h>/* replace every occurance of string x with string y */char *zstring_replace_str(char *str, constchar *x, constchar *y){
char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
int len_str=0, len_y=0, len_x=0;
/* string length */for(; *tmp_y; ++len_y, ++tmp_y)
;
for(; *tmp_str; ++len_str, ++tmp_str)
;
for(; *tmp_x; ++len_x, ++tmp_x)
;
/* Bounds check */if (len_y >= len_str)
return str;
/* reset tmp pointers */
tmp_y = y;
tmp_x = x;
for (tmp_str = str ; *tmp_str; ++tmp_str)
if(*tmp_str == *tmp_x) {
/* save tmp_str */for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
/* Reached end of x, we got something to replace then!
* Copy y only if there is enough room for it
*/for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
*tmp_str = *tmp_y;
}
/* reset tmp_x */
tmp_x = x;
}
return str;
}
intmain(){
char s[]="Free software is a matter of liberty, not price.\n""To understand the concept, you should think of 'free' \n""as in 'free speech', not as in 'free beer'";
printf("%s\n\n",s);
printf("%s\n",zstring_replace_str(s,"ree","XYZ"));
return0;
}
Dan di bawah ini adalah hasilnya
Free software is a matter of liberty, not price.
To understand the concept, you should think of 'free'
as in 'free speech', not as in 'free beer'
FXYZ software is a matter of liberty, not price.
To understand the concept, you should think of 'fXYZ'
as in 'fXYZ speech', not as in 'fXYZ beer'
char * str_replace(char * text,char * rep, char * repw){//text -> to replace in it | rep -> replace | repw -> replace withint replen = strlen(rep),repwlen = strlen(repw),count;//some constant variablesfor(int i=0;i<strlen(text);i++){//search for the first character from rep in textif(text[i] == rep[0]){//if it found it
count = 1;//start searching from the next character to avoid repetitionfor(int j=1;j<replen;j++){
if(text[i+j] == rep[j]){//see if the next character in text is the same as the next in the rep if not break
count++;
}else{
break;
}
}
if(count == replen){//if count equals to the lenght of the rep then we found the word that we want to replace in the textif(replen < repwlen){
for(int l = strlen(text);l>i;l--){//cuz repwlen greater than replen we need to shift characters to the right to make space for the replacement to fit
text[l+repwlen-replen] = text[l];//shift by repwlen-replen
}
}
if(replen > repwlen){
for(int l=i+replen-repwlen;l<strlen(text);l++){//cuz replen greater than repwlen we need to shift the characters to the left
text[l-(replen-repwlen)] = text[l];//shift by replen-repwlen
}
text[strlen(text)-(replen-repwlen)] = '\0';//get rid of the last unwanted characters
}
for(int l=0;l<repwlen;l++){//replace rep with repwlen
text[i+l] = repw[l];
}
if(replen != repwlen){
i+=repwlen-1;//pass to the next character | try text "y" ,rep "y",repw "yy" without this line to understand
}
}
}
}
return text;
}
jika Anda ingin kode strlen untuk menghindari pemanggilan string.h
intstrlen(char * string){//use this code to avoid calling string.hint lenght = 0;
while(string[lenght] != '\0'){
lenght++;
}
return lenght;
}
Jawaban:
Pengoptimal harus menghilangkan sebagian besar variabel lokal. Penunjuk tmp ada di sana untuk memastikan strcpy tidak harus menjalankan string untuk menemukan null. tmp menunjuk ke akhir hasil setelah setiap panggilan. (Lihat algoritma Shlemiel pelukis untuk mengapa strcpy bisa mengganggu.)
// You must free the result if result is non-NULL. char *str_replace(char *orig, char *rep, char *with) { char *result; // the return string char *ins; // the next insert point char *tmp; // varies int len_rep; // length of rep (the string to remove) int len_with; // length of with (the string to replace rep with) int len_front; // distance between rep and end of last rep int count; // number of replacements // sanity checks and initialization if (!orig || !rep) return NULL; len_rep = strlen(rep); if (len_rep == 0) return NULL; // empty rep causes infinite loop during count if (!with) with = ""; len_with = strlen(with); // count the number of replacements needed ins = orig; for (count = 0; tmp = strstr(ins, rep); ++count) { ins = tmp + len_rep; } tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1); if (!result) return NULL; // first time through the loop, all the variable are set correctly // from here on, // tmp points to the end of the result string // ins points to the next occurrence of rep in orig // orig points to the remainder of orig after "end of rep" while (count--) { ins = strstr(orig, rep); len_front = ins - orig; tmp = strncpy(tmp, orig, len_front) + len_front; tmp = strcpy(tmp, with) + len_with; orig += len_front + len_rep; // move to next "end of rep" } strcpy(tmp, orig); return result; }
sumber
size_t
sebagai penggantiint
ukuran objek / string arbitrer dan indeks ke dalamnya. Juga, apa tujuanstrcpy(tmp, orig);
akhirnya? Sepertinya salah.for
loop pertama denganfor (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}
, kemudiantmp
hanya digunakan untuk menulis.Ini tidak tersedia di pustaka C standar karena, dengan hanya diberi karakter * Anda tidak dapat menambah memori yang dialokasikan ke string jika string pengganti lebih panjang dari string yang diganti.
Anda dapat melakukan ini dengan lebih mudah menggunakan std :: string, tetapi bahkan di sana, tidak ada fungsi tunggal yang akan melakukannya untuk Anda.
sumber
Tidak ada satupun.
Anda harus menggulungnya sendiri menggunakan sesuatu seperti strstr dan strcat atau strcpy.
sumber
strcat()
adalah saran yang buruk.Anda dapat membangun fungsi replace Anda sendiri menggunakan strstr untuk menemukan substring dan strncpy untuk disalin sebagian ke buffer baru.
Kecuali jika Anda ingin
replace_with
memiliki panjang yang sama dengan yang Anda inginkanreplace
, mungkin yang terbaik adalah menggunakan buffer baru untuk menyalin string baru.sumber
Karena string di C tidak dapat tumbuh secara dinamis di tempat, substitusi umumnya tidak akan berfungsi. Oleh karena itu Anda perlu mengalokasikan ruang untuk string baru yang memiliki cukup ruang untuk substitusi Anda dan kemudian menyalin bagian-bagian dari aslinya ditambah substitusi ke string baru. Untuk menyalin bagian-bagian Anda akan menggunakan strncpy .
sumber
Berikut beberapa contoh kode yang melakukannya.
#include <string.h> #include <stdlib.h> char * replace( char const * const original, char const * const pattern, char const * const replacement ) { size_t const replen = strlen(replacement); size_t const patlen = strlen(pattern); size_t const orilen = strlen(original); size_t patcnt = 0; const char * oriptr; const char * patloc; // find how many times the pattern occurs in the original string for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) { patcnt++; } { // allocate memory for the new string size_t const retlen = orilen + patcnt * (replen - patlen); char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) ); if (returned != NULL) { // copy the original string, // replacing all the instances of the pattern char * retptr = returned; for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) { size_t const skplen = patloc - oriptr; // copy the section until the occurence of the pattern strncpy(retptr, oriptr, skplen); retptr += skplen; // copy the replacement strncpy(retptr, replacement, replen); retptr += replen; } // copy the rest of the string. strcpy(retptr, oriptr); } return returned; } } #include <stdio.h> int main(int argc, char * argv[]) { if (argc != 4) { fprintf(stderr,"usage: %s <original text> <pattern> <replacement>\n", argv[0]); exit(-1); } else { char * const newstr = replace(argv[1], argv[2], argv[3]); if (newstr) { printf("%s\n", newstr); free(newstr); } else { fprintf(stderr,"allocation error\n"); exit(-2); } } return 0; }
sumber
// Here is the code for unicode strings! int mystrstr(wchar_t *txt1,wchar_t *txt2) { wchar_t *posstr=wcsstr(txt1,txt2); if(posstr!=NULL) { return (posstr-txt1); }else { return -1; } } // assume: supplied buff is enough to hold generated text void StringReplace(wchar_t *buff,wchar_t *txt1,wchar_t *txt2) { wchar_t *tmp; wchar_t *nextStr; int pos; tmp=wcsdup(buff); pos=mystrstr(tmp,txt1); if(pos!=-1) { buff[0]=0; wcsncpy(buff,tmp,pos); buff[pos]=0; wcscat(buff,txt2); nextStr=tmp+pos+wcslen(txt1); while(wcslen(nextStr)!=0) { pos=mystrstr(nextStr,txt1); if(pos==-1) { wcscat(buff,nextStr); break; } wcsncat(buff,nextStr,pos); wcscat(buff,txt2); nextStr=nextStr+pos+wcslen(txt1); } } free(tmp); }
sumber
Itu repl_str () di creativeandcritical.net cepat dan dapat diandalkan. Juga disertakan di halaman itu adalah varian string lebar, repl_wcs () , yang dapat digunakan dengan string Unicode termasuk yang dikodekan dalam UTF-8, melalui fungsi pembantu - kode demo ditautkan dari halaman. Pengungkapan penuh terlambat: Saya adalah penulis halaman itu dan fungsi di dalamnya.
sumber
pos_cache = realloc(pos_cache
free(pos_cache);
fungsi di akhir.realloc
mungkin gagal. Jika ya, itu kembaliNULL
dan meninggalkan penunjuk lama utuh.p = realloc(p, x)
akan, jika gagal, menulis ulang penunjuk heap yang validp
denganNULL
, dan jika itup
adalah satu-satunya referensi Anda ke objek heap tersebut, Anda telah membocorkannya. Ini kesalahan pemula yang klasik.saya menemukan sebagian besar fungsi yang diusulkan sulit dipahami - jadi saya datang dengan ini:
static char *dull_replace(const char *in, const char *pattern, const char *by) { size_t outsize = strlen(in) + 1; // TODO maybe avoid reallocing by counting the non-overlapping occurences of pattern char *res = malloc(outsize); // use this to iterate over the output size_t resoffset = 0; char *needle; while (needle = strstr(in, pattern)) { // copy everything up to the pattern memcpy(res + resoffset, in, needle - in); resoffset += needle - in; // skip the pattern in the input-string in = needle + strlen(pattern); // adjust space for replacement outsize = outsize - strlen(pattern) + strlen(by); res = realloc(res, outsize); // copy the pattern memcpy(res + resoffset, by, strlen(by)); resoffset += strlen(by); } // copy the remaining input strcpy(res + resoffset, in); return res; }
keluaran harus dibebaskan
sumber
Anda dapat menggunakan fungsi ini (komentar menjelaskan cara kerjanya):
void strreplace(char *string, const char *find, const char *replaceWith){ if(strstr(string, replaceWith) != NULL){ char *temporaryString = malloc(strlen(strstr(string, find) + strlen(find)) + 1); strcpy(temporaryString, strstr(string, find) + strlen(find)); //Create a string with what's after the replaced part *strstr(string, find) = '\0'; //Take away the part to replace and the part after it in the initial string strcat(string, replaceWith); //Concat the first part of the string with the part to replace with strcat(string, temporaryString); //Concat the first part of the string with the part after the replaced part free(temporaryString); //Free the memory to avoid memory leaks } }
sumber
Ini yang saya buat berdasarkan persyaratan ini:
Ganti pola terlepas dari apakah panjang atau pendek.
Tidak menggunakan malloc apa pun (eksplisit atau implisit) untuk menghindari kebocoran memori secara intrinsik.
Ganti sejumlah kemunculan pola.
Toleransi ganti string yang memiliki substring sama dengan string pencarian.
Tidak harus memeriksa apakah Line array cukup besar untuk menampung penggantinya. misalnya Ini tidak bekerja kecuali pemanggil mengetahui bahwa ukuran baris cukup untuk menampung string baru.
/* returns number of strings replaced. */ int replacestr(char *line, const char *search, const char *replace) { int count; char *sp; // start of pattern //printf("replacestr(%s, %s, %s)\n", line, search, replace); if ((sp = strstr(line, search)) == NULL) { return(0); } count = 1; int sLen = strlen(search); int rLen = strlen(replace); if (sLen > rLen) { // move from right to left char *src = sp + sLen; char *dst = sp + rLen; while((*dst = *src) != '\0') { dst++; src++; } } else if (sLen < rLen) { // move from left to right int tLen = strlen(sp) - sLen; char *stop = sp + rLen; char *src = sp + sLen + tLen; char *dst = sp + rLen + tLen; while(dst >= stop) { *dst = *src; dst--; src--; } } memcpy(sp, replace, rLen); count += replacestr(sp + rLen, search, replace); return(count); }
Setiap saran untuk meningkatkan kode ini diterima dengan senang hati. Posting saja komentarnya dan saya akan mengujinya.
sumber
Ini milik saya, jadikan semuanya karakter *, yang membuat panggilan lebih mudah ...
char *strrpc(char *str,char *oldstr,char *newstr){ char bstr[strlen(str)]; memset(bstr,0,sizeof(bstr)); int i; for(i = 0;i < strlen(str);i++){ if(!strncmp(str+i,oldstr,strlen(oldstr))){ strcat(bstr,newstr); i += strlen(oldstr) - 1; }else{ strncat(bstr,str + i,1); } } strcpy(str,bstr); return str; }
sumber
Anda dapat menggunakan strrep ()
char * strrep (const char * cadena, const char * strf, const char * strr)
strrep (Ganti String). Mengganti 'strf' dengan 'strr' di 'cadena' dan mengembalikan string baru. Anda perlu membebaskan string yang dikembalikan dalam kode Anda setelah menggunakan strrep.
Parameter cadena String dengan teks. strf Teks untuk ditemukan. strr Teks pengganti.
Returns Teks diperbarui dengan penggantinya.
Proyek dapat ditemukan di https://github.com/ipserc/strrep
sumber
perbaikan respons fann95, menggunakan modifikasi string di tempat, dan mengasumsikan buffer yang ditunjukkan oleh baris cukup besar untuk menahan string yang dihasilkan.
static void replacestr(char *line, const char *search, const char *replace) { char *sp; if ((sp = strstr(line, search)) == NULL) { return; } int search_len = strlen(search); int replace_len = strlen(replace); int tail_len = strlen(sp+search_len); memmove(sp+replace_len,sp+search_len,tail_len+1); memcpy(sp, replace, replace_len); }
sumber
Begitulah .... ini adalah fungsi untuk mengganti setiap kemunculan
char x
denganchar y
dalam string karakterstr
char *zStrrep(char *str, char x, char y){ char *tmp=str; while(*tmp) if(*tmp == x) *tmp++ = y; /* assign first, then incement */ else *tmp++; *tmp='\0'; return str; }
Contoh penggunaan bisa jadi
Exmaple Usage char s[]="this is a trial string to test the function."; char x=' ', y='_'; printf("%s\n",zStrrep(s,x,y)); Example Output this_is_a_trial_string_to_test_the_function.
Fungsinya berasal dari pustaka string yang saya pertahankan di Github , Anda dipersilakan untuk melihat fungsi lain yang tersedia atau bahkan berkontribusi pada kode :)
https://github.com/fnoyanisi/zString
EDIT: @siride benar, fungsi di atas hanya menggantikan karakter. Baru aja yang ini, yang menggantikan string karakter.
#include <stdio.h> #include <stdlib.h> /* replace every occurance of string x with string y */ char *zstring_replace_str(char *str, const char *x, const char *y){ char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y; int len_str=0, len_y=0, len_x=0; /* string length */ for(; *tmp_y; ++len_y, ++tmp_y) ; for(; *tmp_str; ++len_str, ++tmp_str) ; for(; *tmp_x; ++len_x, ++tmp_x) ; /* Bounds check */ if (len_y >= len_str) return str; /* reset tmp pointers */ tmp_y = y; tmp_x = x; for (tmp_str = str ; *tmp_str; ++tmp_str) if(*tmp_str == *tmp_x) { /* save tmp_str */ for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr) if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){ /* Reached end of x, we got something to replace then! * Copy y only if there is enough room for it */ for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str) *tmp_str = *tmp_y; } /* reset tmp_x */ tmp_x = x; } return str; } int main() { char s[]="Free software is a matter of liberty, not price.\n" "To understand the concept, you should think of 'free' \n" "as in 'free speech', not as in 'free beer'"; printf("%s\n\n",s); printf("%s\n",zstring_replace_str(s,"ree","XYZ")); return 0; }
Dan di bawah ini adalah hasilnya
Free software is a matter of liberty, not price. To understand the concept, you should think of 'free' as in 'free speech', not as in 'free beer' FXYZ software is a matter of liberty, not price. To understand the concept, you should think of 'fXYZ' as in 'fXYZ speech', not as in 'fXYZ beer'
sumber
/*замена символа в строке*/ char* replace_char(char* str, char in, char out) { char * p = str; while(p != '\0') { if(*p == in) *p == out; ++p; } return str; }
sumber
DWORD ReplaceString(__inout PCHAR source, __in DWORD dwSourceLen, __in const char* pszTextToReplace, __in const char* pszReplaceWith) { DWORD dwRC = NO_ERROR; PCHAR foundSeq = NULL; PCHAR restOfString = NULL; PCHAR searchStart = source; size_t szReplStrcLen = strlen(pszReplaceWith), szRestOfStringLen = 0, sztextToReplaceLen = strlen(pszTextToReplace), remainingSpace = 0, dwSpaceRequired = 0; if (strcmp(pszTextToReplace, "") == 0) dwRC = ERROR_INVALID_PARAMETER; else if (strcmp(pszTextToReplace, pszReplaceWith) != 0) { do { foundSeq = strstr(searchStart, pszTextToReplace); if (foundSeq) { szRestOfStringLen = (strlen(foundSeq) - sztextToReplaceLen) + 1; remainingSpace = dwSourceLen - (foundSeq - source); dwSpaceRequired = szReplStrcLen + (szRestOfStringLen); if (dwSpaceRequired > remainingSpace) { dwRC = ERROR_MORE_DATA; } else { restOfString = CMNUTIL_calloc(szRestOfStringLen, sizeof(CHAR)); strcpy_s(restOfString, szRestOfStringLen, foundSeq + sztextToReplaceLen); strcpy_s(foundSeq, remainingSpace, pszReplaceWith); strcat_s(foundSeq, remainingSpace, restOfString); } CMNUTIL_free(restOfString); searchStart = foundSeq + szReplStrcLen; //search in the remaining str. (avoid loops when replWith contains textToRepl } } while (foundSeq && dwRC == NO_ERROR); } return dwRC; }
sumber
char *replace(const char*instring, const char *old_part, const char *new_part) { #ifndef EXPECTED_REPLACEMENTS #define EXPECTED_REPLACEMENTS 100 #endif if(!instring || !old_part || !new_part) { return (char*)NULL; } size_t instring_len=strlen(instring); size_t new_len=strlen(new_part); size_t old_len=strlen(old_part); if(instring_len<old_len || old_len==0) { return (char*)NULL; } const char *in=instring; const char *found=NULL; size_t count=0; size_t out=0; size_t ax=0; char *outstring=NULL; if(new_len> old_len ) { size_t Diff=EXPECTED_REPLACEMENTS*(new_len-old_len); size_t outstring_len=instring_len + Diff; outstring =(char*) malloc(outstring_len); if(!outstring){ return (char*)NULL; } while((found = strstr(in, old_part))!=NULL) { if(count==EXPECTED_REPLACEMENTS) { outstring_len+=Diff; if((outstring=realloc(outstring,outstring_len))==NULL) { return (char*)NULL; } count=0; } ax=found-in; strncpy(outstring+out,in,ax); out+=ax; strncpy(outstring+out,new_part,new_len); out+=new_len; in=found+old_len; count++; } } else { outstring =(char*) malloc(instring_len); if(!outstring){ return (char*)NULL; } while((found = strstr(in, old_part))!=NULL) { ax=found-in; strncpy(outstring+out,in,ax); out+=ax; strncpy(outstring+out,new_part,new_len); out+=new_len; in=found+old_len; } } ax=(instring+instring_len)-in; strncpy(outstring+out,in,ax); out+=ax; outstring[out]='\0'; return outstring; }
sumber
Fungsi ini hanya berfungsi jika string ur memiliki ruang ekstra untuk panjang baru
void replace_str(char *str,char *org,char *rep) { char *ToRep = strstr(str,org); char *Rest = (char*)malloc(strlen(ToRep)); strcpy(Rest,((ToRep)+strlen(org))); strcpy(ToRep,rep); strcat(ToRep,Rest); free(Rest); }
Ini hanya menggantikan kemunculan pertama
sumber
Ini dia milik saya, itu mandiri dan serbaguna, serta efisien, itu menumbuhkan atau menyusutkan buffer sesuai kebutuhan di setiap rekursi
void strreplace(char *src, char *str, char *rep) { char *p = strstr(src, str); if (p) { int len = strlen(src)+strlen(rep)-strlen(str); char r[len]; memset(r, 0, len); if ( p >= src ){ strncpy(r, src, p-src); r[p-src]='\0'; strncat(r, rep, strlen(rep)); strncat(r, p+strlen(str), p+strlen(str)-src+strlen(src)); strcpy(src, r); strreplace(p+strlen(rep), str, rep); } } }
sumber
Menggunakan hanya strlen dari string.h
maaf untuk bahasa inggris saya
char * str_replace(char * text,char * rep, char * repw){//text -> to replace in it | rep -> replace | repw -> replace with int replen = strlen(rep),repwlen = strlen(repw),count;//some constant variables for(int i=0;i<strlen(text);i++){//search for the first character from rep in text if(text[i] == rep[0]){//if it found it count = 1;//start searching from the next character to avoid repetition for(int j=1;j<replen;j++){ if(text[i+j] == rep[j]){//see if the next character in text is the same as the next in the rep if not break count++; }else{ break; } } if(count == replen){//if count equals to the lenght of the rep then we found the word that we want to replace in the text if(replen < repwlen){ for(int l = strlen(text);l>i;l--){//cuz repwlen greater than replen we need to shift characters to the right to make space for the replacement to fit text[l+repwlen-replen] = text[l];//shift by repwlen-replen } } if(replen > repwlen){ for(int l=i+replen-repwlen;l<strlen(text);l++){//cuz replen greater than repwlen we need to shift the characters to the left text[l-(replen-repwlen)] = text[l];//shift by replen-repwlen } text[strlen(text)-(replen-repwlen)] = '\0';//get rid of the last unwanted characters } for(int l=0;l<repwlen;l++){//replace rep with repwlen text[i+l] = repw[l]; } if(replen != repwlen){ i+=repwlen-1;//pass to the next character | try text "y" ,rep "y",repw "yy" without this line to understand } } } } return text; }
jika Anda ingin kode strlen untuk menghindari pemanggilan string.h
int strlen(char * string){//use this code to avoid calling string.h int lenght = 0; while(string[lenght] != '\0'){ lenght++; } return lenght; }
sumber