C - wcstok () неправильные результаты - PullRequest
0 голосов
/ 15 декабря 2018

В моей программе возникла проблема с одной из функций.У меня есть текст, который состоит из предложений.В каждом предложении мне нужно найти символы '@', '#', '%' и изменить их на "(at)", "<решетка>", "".И я делаю это с помощью wcstok, потому что я работаю с русским языком.И у меня есть следующие проблемы.

Ввод:

Он был стариком, который ловил рыбу один на скифе вГольфстрим и он уже восемьдесят четыре дня не ловили рыбу.В первые сорок дней мальчик был с ним.Но после сорока дней без рыбы родители мальчика сказали ему, что старик теперь определенно и, наконец, sa @ lao, что является худшей формой неудачи, и мальчик пошел по их приказу в другой лодке, которая поймала трех хороших рыбаков.#h первая неделя.

Вывод:

Он был стариком, который ловил рыбу один на скифе вГольфстрим, и он уже восемьдесят четыре дня не ловил рыбу.В первые сорок дней мальчик был с ним.B (at) (at) f (at) er для (at) yd (at) ys wi (at) ho (at) (at) fish (at) p (at) ren мальчика (at) sh (at)d (at) старый его (at) h (at) (at) он старый m (at) nw (at) s теперь определенно (at) только (at) и fin (at) lly s (at) l (at)о, который (в) он носит (в) форме (в) нл (в) cky, (в) nd (в) он мальчик h (в) d ушел (в) (в) наследники заказов в (в)нет (у) ее бо (у), с которой (у) гх (у) (у) нет, хорошо хорошо (у) ч (у) у него первая (у) неделя.

Как видите, все буквы "a" и "t" заменяются на "(at)".И я не понимаю, почему это происходит.То же самое и с русскими буквами.Это две функции, которые отвечают за эту работу.

void changeSomeSymbols(Text *text) {
wchar_t atSymbol = L'@';
wchar_t atString[5] = L"(at)";
wchar_t percentSymbol = L'%';
wchar_t percentString[10] = L"<percent>";
wchar_t barsSymbol = L'#';
wchar_t barsString[10] = L"<решетка>";
for (int i = 0; i < text->textSize; i++) {
    for (int j = 0; j < text->sentences[i].sentenceSize; j++) {
        switch (text->sentences[i].symbols[j])
        {
        case L'@':
            changeSentence(&(text->sentences[i]), &atSymbol, atString);
            break;
        case L'#':
            changeSentence(&(text->sentences[i]), &barsSymbol, barsString);
            break;
        case L'%':
            changeSentence(&(text->sentences[i]), &percentSymbol, percentString);
            break;
        default:
            break;
        }
    }
}

}

void changeSentence(Sentence *sentence, wchar_t *flagSymbol, wchar_t *insertWstr) {
wchar_t *pwc;
wchar_t *newWcsentence;
wchar_t *buffer;
int insertionSize;
int tokenSize;
int newSentenceSize = 0;
insertionSize = wcslen(insertWstr);
newWcsentence = (wchar_t*)malloc(1 * sizeof(wchar_t));
newWcsentence[0] = L'\0';
pwc = wcstok(sentence->symbols, flagSymbol, &buffer);
do {
    tokenSize = wcslen(pwc);
    newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize + tokenSize + 1) * sizeof(wchar_t));
    newSentenceSize += tokenSize;
    wcscat(newWcsentence, pwc);
    newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize + insertionSize + 1) * sizeof(wchar_t));
    newSentenceSize += insertionSize;
    wcscat(newWcsentence, insertWstr);
    pwc = wcstok(NULL, flagSymbol, &buffer);
} while (pwc != NULL);
newSentenceSize -= insertionSize;
newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize) * sizeof(wchar_t));
newWcsentence[newSentenceSize] = '\0';
free(sentence->symbols);
sentence->symbols = (wchar_t*)malloc((newSentenceSize + 1) * sizeof(wchar_t));
wcscpy(sentence->symbols, newWcsentence);
sentence->sentenceSize = newSentenceSize;
free(pwc);
free(newWcsentence);

}

1 Ответ

0 голосов
/ 16 декабря 2018

Text и Sentence не определены, неясно, какими они должны быть.Просто сделай это в одной функции.

void realloc_and_copy(wchar_t** dst, int *dstlen, const wchar_t *src)
{
    if(!src)
        return;
    int srclen = wcslen(src);
    *dst = realloc(*dst, (*dstlen + srclen + 1) * sizeof(wchar_t));
    if (*dstlen)
        wcscat(*dst, src);
    else
        wcscpy(*dst, src);
    *dstlen += srclen;
}

int main()
{
    const wchar_t* src = L"He was an old man who fished alone in a skiff \
in the Gulf Stream and he had gone eighty - four days now without tak%ing a fish.\
In the first forty days a boy had been with him.But after forty days without a fish \
the boy’s parents had told him that the old man was now definitely and finally sa@lao, \
which is the worst form of unlucky, and the boy had gone at their orders in another \
boat which caught three good fis#h the first week.";

    wchar_t *buf = wcsdup(src);
    wchar_t *dst = NULL;
    int dstlen = 0;

    wchar_t *context = NULL;
    const wchar_t* delimiter = L"@#%";
    wchar_t *token = wcstok(buf, delimiter, &context);
    while(token)
    {
        const wchar_t* modify = NULL;
        int cursor = token - buf - 1;
        if (cursor >= 0)
            switch(src[cursor])
            {
            case L'@': modify = L"(at)"; break;
            case L'%': modify = L"<percent>"; break;
            case L'#': modify = L"<решетка>"; break;
            }

        //append modified text
        realloc_and_copy(&dst, &dstlen, modify);

        //append token
        realloc_and_copy(&dst, &dstlen, token);

        token = wcstok(NULL, delimiter, &context);
    }

    wprintf(L"%s\n", dst);

    free(buf);
    free(dst);

    return 0;
}
...