Заменить все числа в строке Си

Помогите, пожалуйста.
Задача:
Заменить все числа в строке на слово "NUM".

Строка подобного плана:
"str, 123 gdg1(75); test32 0"

После замены строка должна выглядеть так:
"str, NUM gdg1(NUM); test32 NUM"

Использовать можно только стандартную библиотеку си.

Вот, набросал пока что такой вариант. Но если вместо NUM указать очень длинную строку (более 800 символов), заменяет только первое число (123) char* GetNumFromStr(char* tempBuff, int strSize, int i) { static char numFromStr[1024];

    for (int i1 = i; ; i1++)
    {
        if (!isdigit(tempBuff[i1]))
        {
            return 0;
        }

        static char singleNum[1024];
        sprintf(singleNum, "%c", tempBuff[i1]);
        strcat(numFromStr, singleNum);

        if (!isdigit(tempBuff[i1 + 1]))
        {
            return numFromStr;
        }
    }

    return 0;
}

//code from https://ru.stackoverflow.com/questions/60089/
void StrReplace(char str[], char a[], char b[], char buffer[])
{
    int i, j, pos = 0;
    for (i = 0; str[i]; i++)
    {
        for (j = 0; str[i + j] && a[j]; j++)   //начинается ли с i-ой позиции строка a
            if (str[i + j] != a[j])
                break;
        if (!a[j])  //если a[j]=0, то мы дошли до конца строки a
        {
            i += j - 1;  //в j у нас длина стоки a, которую мы перепрыгиваем
            for (j = 0; b[j]; j++)
                buffer[pos++] = b[j];  //на место стоки a ставим строку b
        }
        else
        {
            buffer[pos++] = str[i];   //просто копируем символ
        }
        buffer[pos] = NULL;  //ставим конец строки
    }
    strcpy(str, buffer);  //копируем в первоначальную строку
}

int main()
{
    char* tempBuff = (char*)"str, 123 gdg1(75); test32 0";
    int strSize = strlen(tempBuff);

    for (int i = 0; i < strSize; i++)
    {
        if (isdigit(tempBuff[i]))
        {
            char* numFromStr;
            numFromStr = GetNumFromStr(tempBuff, strSize, i);

            if (numFromStr != 0)
            {
                static char tempStr[1024 * 4];
                StrReplace(tempBuff, numFromStr, (char*)"NUM", tempStr);
                memset(numFromStr, 0, sizeof(char) * 1024);
            }
        }
    }

    printf("%s", tempBuff);

    return 0;
}

Если заменять на очень длинную строку - результат следующий: "str, gg.......gg gdg1(75); test32 0"
Но если заменять просто на строку "NUM", то почти корректно отрабатывает:
"str, NUM gdgNUM(75); test32 NUM"


Ответы (1 шт):

Автор решения: 0andriy

Мне лень разбираться, что там написано в коде.

static char *put_replacement(char *out, const char *r, size_t len)
{
    memcpy(out, r, len);
    return out + len;
}

static void replace(const char *in, char *out, size_t outlen)
{
    const char *r = "NUM";
    const char *q;
    int flag = 0;
    char p;

    while ((p = *in++)) {
        if (flag == 0) {
            if (isdigit(p)) {
                q = in - 1;
                flag = 1;
                continue;
            }
            if (isalpha(p))
                flag = 2;
        }

        if (flag == 1) {
            if (isdigit(p))
                continue;
            if (isalpha(p)) {
                out = put_replacement(out, q, in - 1 - q);
                flag = 2;
            } else {
                out = put_replacement(out, r, strlen(r));
                flag = 0;
            }
        }

        if (flag == 2 && !(isalpha(p) || isdigit(p))) {
            flag = 0;
        }

        *out++ = p;
    }

    if (flag == 1)
        out = put_replacement(out, r, strlen(r));

    *out++ = '\0';
}

Полный текст программы

$ gcc -O2 -Wall -o num-replace num-replace.c && ./num-replace 
in: str, 123 gdg1(75); test32 0
out: str, NUM gdg1(NUM); test32 NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_1 && ./num-replace 
in: 1str, 123 gdg1(75); test32 0
out: 1str, NUM gdg1(NUM); test32 NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_2 && ./num-replace 
in: 1 str, 123 gdg1(75); test32 0
out: NUM str, NUM gdg1(NUM); test32 NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_3 && ./num-replace 
in: str, 123 gdg1(75); test32 0s
out: str, NUM gdg1(NUM); test32 0s

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_4 && ./num-replace 
in: str, 123 gdg1(75); test32 0 s
out: str, NUM gdg1(NUM); test32 NUM s

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_5 && ./num-replace 
in: str, 123 gdg1(75); test32 1d1 0
out: str, NUM gdg1(NUM); test32 1d1 NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_6 && ./num-replace 
in: str, 123 gdg1(75); test32 d1d 0
out: str, NUM gdg1(NUM); test32 d1d NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_7 && ./num-replace 
in: 1 123 1 75 3 1
out: NUM NUM NUM NUM NUM NUM

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_8 && ./num-replace 
in: a bcd e fg h j
out: a bcd e fg h j

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_9 && ./num-replace 
in: a
out: a

$ gcc -O2 -Wall -o num-replace num-replace.c -DTEST_10 && ./num-replace 
in: 0
out: NUM
→ Ссылка