Якою функцією є заміна підрядка з рядка в C?


94

Отримавши char *рядок ( ), я хочу знайти всі випадки підрядка і замінити їх на альтернативний рядок. Я не бачу жодної простої функції, яка досягає цього в <string.h>.


4
Я сумніваюся, що ви можете зробити це
змінним

Відповіді:


87

Оптимізатор повинен усунути більшість локальних змінних. Вказівник tmp є там, щоб переконатися, що strcpy не повинен ходити по рядку, щоб знайти нуль. tmp вказує на кінець результату після кожного дзвінка. (Див. Алгоритм художника Шлеміеля про те, чому strcpy може дратувати.)

// 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;
}

@jmucchiello: використовувати size_tзамість intдовільних розмірів об'єктів / рядків та індексів до них. Крім того, яка мета strcpy(tmp, orig);в самому кінці? Це здається неправильним.
Олексій Фрунзе

@Alex, останній strcpy (tmp, orig) копіює останню частину рядка до місця призначення. Наприклад: замінити ("abab", "a", "c") в кінці циклу, результат містить, "cbc" та оригінал вказує на останній "b" у "abab". Останній strcpy додає "b", тому повертається рядок "cbcb". Якщо нічого не залишається для копіювання, orig повинен вказувати на ASCIIZ вхідного рядка.
jmucchiello

спрощення: ви можете замінити цей перший forцикл на for (count = 1; ins = strstr(ins + rep_len, rep); ++count) {}, потім tmpвикористовується лише для запису.
чемпіон

1
char * done = replace ("abcdefghijkl", "bc", "yz"); do_stuff (); безкоштовно (зроблено);
jmucchiello

2
Зауважте, що ця функція повертає NULL, якщо немає випадків, щоб замінити (if (! (Ins = strstr (orig, rep))) повертає NULL;). Ви не можете просто використовувати вихідні дані, вам потрібно перевірити, чи є вихід NULL, і якщо так, використовуйте оригінальний рядок (не просто копіюйте вказівник на рядок результату, оскільки free (result) звільняє початковий рядок). Використання є більш простим, якщо вхідний рядок просто копіюється у вихідний рядок, якщо немає чим замінити.
Adversus

18

Цього не передбачено у стандартній бібліотеці C, оскільки, маючи лише символ *, ви не можете збільшити пам’ять, виділену для рядка, якщо рядок заміни довший за рядок, який замінюється.

Ви можете зробити це за допомогою std :: string простіше, але навіть там жодна функція не зробить це за вас.


12
Це питання стосується С, а не С ++.
Геремія

1 / strlen (char *) + 1 не обов'язково дорівнює розміру сховища. 2 / Існує багато N версій рядкових функцій, які отримують, і додатковий параметр розміру буфера, тому немає жодної причини, чому не могло бути snreplace (). 3 / може бути функція заміни на місці, а не функція заміни на місці. 4 / як ви думаєте, як працює sprintf? Він отримує аргумент char *, і йому не потрібно збільшувати виділення пам'яті, тому жодна причина заміни також не може працювати ... (хоча C має поганий дизайн "рядка", і розмір буфера завжди повинен передаватися з покажчиком => snprintf)
Стівен Спарк

12

Немає жодного.

Вам потрібно буде прокрутити свій власний, використовуючи щось на зразок strstr і strcat або strcpy.


7
Де зберігаються колекції шанувальників часто використовуваних функцій? Звичайно, для цього вже існує бібліотека ....
Пейсерер

1
strcat()це погана пропозиція.
Іхароб Аль Асімі

11

Ви можете створити власну функцію заміни, використовуючи strstr для пошуку підрядків та strncpy для копіювання частин у новий буфер.

Якщо те, що ви хочете, replace_withмає однакову довжину з тим, що ви хочете replace, тоді, мабуть, найкраще використовувати новий буфер для копіювання нового рядка.


9

Оскільки рядки в C не можуть динамічно зростати замість заміщення, як правило, не працюватимуть. Тому вам потрібно виділити простір для нового рядка, який має достатньо місця для вашої заміни, а потім скопіювати частини з оригіналу плюс заміну в новий рядок. Щоб скопіювати деталі, які ви б використовували strncpy .


Розмір буфера може бути більшим, ніж strlen, рядок заміни може бути меншим, ніж замінений рядок ... тому вам не потрібно виділяти пам'ять для виконання заміни. (Також на мікроконтролерах у вас може бути нескінченна пам’ять, і, можливо, вам доведеться виконати заміну на місці. Скопіювати все в новий буфер, можливо, не буде правильним рішенням для всіх ...)
Стівен Спарк,

8

Ось зразок коду, який це робить.

#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;
}

Це працює, але трохи глючить, але все одно дякую! : D Ось один, який я знайшов, який працює дуже добре, coding.debuntu.org/... ура! :)
Joe DF

4
// 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);
}

3

Функція repl_str () на creativeandcritical.net є швидкою та надійною. На цій сторінці також є широкий варіант рядка, repl_wcs () , який можна використовувати з рядками Unicode, включаючи кодовані в UTF-8, за допомогою допоміжних функцій - демонстраційний код посилається на сторінку. Повне розкриття інформації із запізненням: Я автор цієї сторінки та функцій на ній.


3
швидкий і надійний, але має величезний витік пам'яті.
MightyPork

3
Я не розумію, як це могло. Існує лише один malloc, і абонент отримує вказівку звільнити пам’ять, коли це більше не потрібно. Чи можете ви бути більш конкретними?
Лейрд

@Lairdpos_cache = realloc(pos_cache
PSkocik

@PSkocik Функція була оновлена ​​після подання скарги @MightyPork, але, незважаючи на те, що тепер у неї є додатковий malloc / realloc для pos_cache, я не бачу шляху коду, який уникає завершення free(pos_cache);функції at.
Лерд

@Laird reallocможе не вдатися. Якщо це сталося, він повертається NULLі залишає старий вказівник недоторканим. p = realloc(p, x)буде, в разі невдачі, переписати дійсний покажчик купи pз NULL, і якщо це pбула ваша єдина посилання на цей об'єкт купи, тепер ви просочилася його. Це класична помилка новачка.
PSkocik,

3

Мені важко зрозуміти більшість із запропонованих функцій - тому я придумав таке:

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;
}

вихід повинен бути вільним


2

Ви можете використовувати цю функцію (коментарі пояснюють, як це працює):

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
    }
}

1

Ось той, який я створив на основі цих вимог:

  1. Замініть шаблон, незалежно від того, довгий чи коротший.

  2. Не використовуйте жодних malloc (явних чи неявних), щоб по суті уникнути витоків пам'яті.

  3. Замініть будь-яку кількість повторень шаблону.

  4. Допустіть рядок заміни, що має підрядок, рівний пошуковому рядку.

  5. Не потрібно перевіряти, чи є масив рядків достатнім розміром для утримання заміни. Наприклад, це не працює, якщо виклик не знає, що рядок є достатнім для розміщення нового рядка.

/* 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);
}

Будь-які пропозиції щодо вдосконалення цього кодексу приймаються з радістю. Просто опублікуйте коментар, і я протестую його.


1

Ви можете використовувати strrep ()

char * strrep (const char * cadena, const char * strf, const char * strr)

strrep (Заміна рядка). Замінює 'strf' на 'strr' у 'cadena' і повертає новий рядок. Вам потрібно звільнити повернутий рядок у коді після використання strrep.

Параметри cadena Рядок з текстом. strf Текст для пошуку. strr Замінний текст.

Повертає Текст, оновлений із заміною.

Проект можна знайти за адресою https://github.com/ipserc/strrep


0

виправлення відповіді fann95, використовуючи модифікацію рядка на місці, і припускаючи, що буфер, на який вказує рядок, є достатньо великим, щоб утримувати результуючий рядок.

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);
}

0

Там ви йдете .... це функція для заміни кожне з входження char xв char yмежах рядка символівstr

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;
}

Прикладом використання може бути

  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.

Функція з бібліотеки рядків, яку я підтримую на Github , більше ніж радий переглянути інші доступні функції або навіть внести свій внесок у код :)

https://github.com/fnoyanisi/zString

EDIT: @siride має рацію, функція вище замінює лише символи. Щойно написав цей, який замінює рядки символів.

#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;
}

А нижче - результат

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'

Це замінює лише окремі символи, а не підрядки.
siride

0
/*замена символа в строке*/
char* replace_char(char* str, char in, char out) {
    char * p = str;

    while(p != '\0') {
        if(*p == in)
            *p == out;
        ++p;
    }

    return str;
}

segfault, коли str нульовий
Code_So1dier

0
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;
}

0
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;
}

0

Ця функція працює, лише якщо у рядка ur є додатковий простір для нової довжини

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);
}

Це замінює лише перше входження


0

Тут іде мій, він автономний і універсальний, а також ефективний, він зростає або скорочує буфери в кожній рекурсії

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);
        }
    }
}

0

Ось моє, зробіть їх усі char *, що полегшує дзвінки ...

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;
}

0

Використання лише strlen з string.h

Вибачте за мою англійську

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;
}

якщо ви хочете, щоб код strlen уникав виклику string.h

int strlen(char * string){//use this code to avoid calling string.h
    int lenght = 0;
    while(string[lenght] != '\0'){
        lenght++;
    }
    return lenght;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.